xref: /lighttpd1.4/src/mod_wolfssl.c (revision d5e899e2)
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: SNI callbacks disabled if wolfSSL is not built OPENSSL_ALL ! */
2045        #ifdef OPENSSL_ALL /* regretable */
2046        #ifdef HAVE_SNI
2047         wolfSSL_CTX_set_servername_callback(
2048             s->ssl_ctx, network_ssl_servername_callback);
2049         wolfSSL_CTX_set_servername_arg(s->ssl_ctx, srv);
2050        #endif             /* regretable */
2051        #else
2052         log_error(srv->errh, __FILE__, __LINE__,
2053           "SSL: WARNING: SNI callbacks *crippled* in wolfSSL library build");
2054         UNUSED(network_ssl_servername_callback);
2055        #endif
2056 
2057        #ifdef HAVE_ALPN
2058        #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2059         SSL_CTX_set_alpn_select_cb(s->ssl_ctx,mod_openssl_alpn_select_cb,NULL);
2060        #endif
2061        #endif
2062       #endif
2063 
2064         if (!s->ssl_use_sslv3 && !s->ssl_use_sslv2
2065             && wolfSSL_CTX_SetMinVersion(s->ssl_ctx, WOLFSSL_TLSV1_2)
2066                != WOLFSSL_SUCCESS)
2067             return -1;
2068 
2069         if (s->ssl_conf_cmd && s->ssl_conf_cmd->used) {
2070             if (0 != mod_openssl_ssl_conf_cmd(srv, s)) return -1;
2071         }
2072 
2073         return 0;
2074 }
2075 
2076 
2077 static int
2078 mod_openssl_set_defaults_sockets(server *srv, plugin_data *p)
2079 {
2080     static const config_plugin_keys_t cpk[] = {
2081       { CONST_STR_LEN("ssl.engine"),
2082         T_CONFIG_BOOL,
2083         T_CONFIG_SCOPE_CONNECTION }
2084      ,{ CONST_STR_LEN("ssl.cipher-list"),
2085         T_CONFIG_STRING,
2086         T_CONFIG_SCOPE_CONNECTION }
2087      ,{ CONST_STR_LEN("ssl.honor-cipher-order"),
2088         T_CONFIG_BOOL,
2089         T_CONFIG_SCOPE_CONNECTION }
2090      ,{ CONST_STR_LEN("ssl.dh-file"),
2091         T_CONFIG_STRING,
2092         T_CONFIG_SCOPE_CONNECTION }
2093      ,{ CONST_STR_LEN("ssl.ec-curve"),
2094         T_CONFIG_STRING,
2095         T_CONFIG_SCOPE_CONNECTION }
2096      ,{ CONST_STR_LEN("ssl.openssl.ssl-conf-cmd"),
2097         T_CONFIG_ARRAY_KVSTRING,
2098         T_CONFIG_SCOPE_CONNECTION }
2099      ,{ CONST_STR_LEN("ssl.pemfile"), /* included to process global scope */
2100         T_CONFIG_STRING,
2101         T_CONFIG_SCOPE_CONNECTION }
2102      ,{ CONST_STR_LEN("ssl.empty-fragments"),
2103         T_CONFIG_BOOL,
2104         T_CONFIG_SCOPE_CONNECTION }
2105      ,{ CONST_STR_LEN("ssl.use-sslv2"),
2106         T_CONFIG_BOOL,
2107         T_CONFIG_SCOPE_CONNECTION }
2108      ,{ CONST_STR_LEN("ssl.use-sslv3"),
2109         T_CONFIG_BOOL,
2110         T_CONFIG_SCOPE_CONNECTION }
2111      ,{ CONST_STR_LEN("ssl.stek-file"),
2112         T_CONFIG_STRING,
2113         T_CONFIG_SCOPE_SERVER }
2114      ,{ NULL, 0,
2115         T_CONFIG_UNSET,
2116         T_CONFIG_SCOPE_UNSET }
2117     };
2118     /* WolfSSL does not have mapping for "HIGH" */
2119     /* cipher list is (current) output of "openssl ciphers HIGH" */
2120     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 };
2121 
2122     p->ssl_ctxs = calloc(srv->config_context->used, sizeof(plugin_ssl_ctx));
2123     force_assert(p->ssl_ctxs);
2124 
2125     int rc = HANDLER_GO_ON;
2126     plugin_data_base srvplug;
2127     memset(&srvplug, 0, sizeof(srvplug));
2128     plugin_data_base * const ps = &srvplug;
2129     if (!config_plugin_values_init(srv, ps, cpk, "mod_openssl"))
2130         return HANDLER_ERROR;
2131 
2132     plugin_config_socket defaults;
2133     memset(&defaults, 0, sizeof(defaults));
2134     defaults.ssl_honor_cipher_order = 1;
2135     defaults.ssl_cipher_list = &default_ssl_cipher_list;
2136 
2137     /* process and validate config directives for global and $SERVER["socket"]
2138      * (init i to 0 if global context; to 1 to skip empty global context) */
2139     for (int i = !ps->cvlist[0].v.u2[1]; i < ps->nconfig; ++i) {
2140         config_cond_info cfginfo;
2141         config_get_config_cond_info(&cfginfo, (uint32_t)ps->cvlist[i].k_id);
2142         int is_socket_scope = (0 == i || cfginfo.comp == COMP_SERVER_SOCKET);
2143         int count_not_engine = 0;
2144 
2145         plugin_config_socket conf;
2146         memcpy(&conf, &defaults, sizeof(conf));
2147 
2148         /*(preserve prior behavior; not inherited)*/
2149         /*(forcing inheritance might break existing configs where SSL is enabled
2150          * by default in the global scope, but not $SERVER["socket"]=="*:80") */
2151         conf.ssl_enabled = 0;
2152 
2153         config_plugin_value_t *cpv = ps->cvlist + ps->cvlist[i].v.u2[0];
2154         for (; -1 != cpv->k_id; ++cpv) {
2155             /* ignore ssl.pemfile (k_id=6); included to process global scope */
2156             if (!is_socket_scope && cpv->k_id != 6) {
2157                 log_error(srv->errh, __FILE__, __LINE__,
2158                   "%s is valid only in global scope or "
2159                   "$SERVER[\"socket\"] condition", cpk[cpv->k_id].k);
2160                 continue;
2161             }
2162             ++count_not_engine;
2163             switch (cpv->k_id) {
2164               case 0: /* ssl.engine */
2165                 conf.ssl_enabled = (0 != cpv->v.u);
2166                 --count_not_engine;
2167                 break;
2168               case 1: /* ssl.cipher-list */
2169                 conf.ssl_cipher_list = cpv->v.b;
2170                 break;
2171               case 2: /* ssl.honor-cipher-order */
2172                 conf.ssl_honor_cipher_order = (0 != cpv->v.u);
2173                 break;
2174               case 3: /* ssl.dh-file */
2175                 conf.ssl_dh_file = cpv->v.b;
2176                 break;
2177               case 4: /* ssl.ec-curve */
2178                 conf.ssl_ec_curve = cpv->v.b;
2179                 break;
2180               case 5: /* ssl.openssl.ssl-conf-cmd */
2181                 *(const array **)&conf.ssl_conf_cmd = cpv->v.a;
2182                 break;
2183               case 6: /* ssl.pemfile */
2184                 /* ignore here; included to process global scope when
2185                  * ssl.pemfile is set, but ssl.engine is not "enable" */
2186                 break;
2187               case 7: /* ssl.empty-fragments */
2188                 conf.ssl_empty_fragments = (0 != cpv->v.u);
2189                 log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2190                   "ssl.empty-fragments is deprecated and will soon be "
2191                   "removed.  It is disabled by default.");
2192                 if (conf.ssl_empty_fragments)
2193                     log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2194                       "If needed, use: ssl.openssl.ssl-conf-cmd = "
2195                       "(\"Options\" => \"EmptyFragments\")");
2196                 log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2197                   "ssl.empty-fragments is a "
2198                   "counter-measure against a SSL 3.0/TLS 1.0 protocol "
2199                   "vulnerability affecting CBC ciphers, which cannot be handled"
2200                   " by some broken (Microsoft) SSL implementations.");
2201                 break;
2202               case 8: /* ssl.use-sslv2 */
2203                 conf.ssl_use_sslv2 = (0 != cpv->v.u);
2204                 log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2205                   "ssl.use-sslv2 is deprecated and will soon be removed.  "
2206                   "It is disabled by default.  "
2207                   "Many modern TLS libraries no longer support SSLv2.");
2208                 break;
2209               case 9: /* ssl.use-sslv3 */
2210                 conf.ssl_use_sslv3 = (0 != cpv->v.u);
2211                 log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2212                   "ssl.use-sslv3 is deprecated and will soon be removed.  "
2213                   "It is disabled by default.  "
2214                   "Many modern TLS libraries no longer support SSLv3.");
2215                 if (conf.ssl_use_sslv3)
2216                     log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2217                       "If needed, use: ssl.openssl.ssl-conf-cmd = "
2218                       "(\"MinProtocol\" => \"SSLv3\")");
2219                 break;
2220               case 10:/* ssl.stek-file */
2221                 if (!buffer_is_empty(cpv->v.b))
2222                     p->ssl_stek_file = cpv->v.b->ptr;
2223                 break;
2224               default:/* should not happen */
2225                 break;
2226             }
2227         }
2228         if (HANDLER_GO_ON != rc) break;
2229         if (0 == i) memcpy(&defaults, &conf, sizeof(conf));
2230 
2231         if (0 != i && !conf.ssl_enabled) continue;
2232 
2233         /* fill plugin_config_socket with global context then $SERVER["socket"]
2234          * only for directives directly in current $SERVER["socket"] condition*/
2235 
2236         /*conf.pc                     = p->defaults.pc;*/
2237         conf.ssl_ca_file              = p->defaults.ssl_ca_file;
2238         conf.ssl_ca_dn_file           = p->defaults.ssl_ca_dn_file;
2239         conf.ssl_ca_crl_file          = p->defaults.ssl_ca_crl_file;
2240         conf.ssl_verifyclient         = p->defaults.ssl_verifyclient;
2241         conf.ssl_verifyclient_enforce = p->defaults.ssl_verifyclient_enforce;
2242         conf.ssl_verifyclient_depth   = p->defaults.ssl_verifyclient_depth;
2243         conf.ssl_read_ahead           = p->defaults.ssl_read_ahead;
2244 
2245         int sidx = ps->cvlist[i].k_id;
2246         for (int j = !p->cvlist[0].v.u2[1]; j < p->nconfig; ++j) {
2247             if (p->cvlist[j].k_id != sidx) continue;
2248             /*if (0 == sidx) break;*//*(repeat to get ssl_pemfile,ssl_privkey)*/
2249             cpv = p->cvlist + p->cvlist[j].v.u2[0];
2250             for (; -1 != cpv->k_id; ++cpv) {
2251                 ++count_not_engine;
2252                 switch (cpv->k_id) {
2253                   case 0: /* ssl.pemfile */
2254                     if (cpv->vtype == T_CONFIG_LOCAL)
2255                         conf.pc = cpv->v.v;
2256                     break;
2257                   case 2: /* ssl.ca-file */
2258                     if (cpv->vtype == T_CONFIG_LOCAL)
2259                         conf.ssl_ca_file = cpv->v.v;
2260                     break;
2261                   case 3: /* ssl.ca-dn-file */
2262                     if (cpv->vtype == T_CONFIG_LOCAL)
2263                         conf.ssl_ca_dn_file = cpv->v.v;
2264                     break;
2265                   case 4: /* ssl.ca-crl-file */
2266                     conf.ssl_ca_crl_file = cpv->v.b;
2267                     break;
2268                   case 5: /* ssl.read-ahead */
2269                     conf.ssl_read_ahead = (0 != cpv->v.u);
2270                     break;
2271                   case 6: /* ssl.disable-client-renegotiation */
2272                     conf.ssl_disable_client_renegotiation = (0 != cpv->v.u);
2273                     break;
2274                   case 7: /* ssl.verifyclient.activate */
2275                     conf.ssl_verifyclient = (0 != cpv->v.u);
2276                     break;
2277                   case 8: /* ssl.verifyclient.enforce */
2278                     conf.ssl_verifyclient_enforce = (0 != cpv->v.u);
2279                     break;
2280                   case 9: /* ssl.verifyclient.depth */
2281                     conf.ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
2282                     break;
2283                   default:
2284                     break;
2285                 }
2286             }
2287             break;
2288         }
2289 
2290         if (NULL == conf.pc) {
2291             if (0 == i && !conf.ssl_enabled) continue;
2292             if (0 != i) {
2293                 /* inherit ssl settings from global scope
2294                  * (if only ssl.engine = "enable" and no other ssl.* settings)
2295                  * (This is for convenience when defining both IPv4 and IPv6
2296                  *  and desiring to inherit the ssl config from global context
2297                  *  without having to duplicate the directives)*/
2298                 if (count_not_engine
2299                     || (conf.ssl_enabled && NULL == p->ssl_ctxs[0].ssl_ctx)) {
2300                     log_error(srv->errh, __FILE__, __LINE__,
2301                       "ssl.pemfile has to be set in same $SERVER[\"socket\"] scope "
2302                       "as other ssl.* directives, unless only ssl.engine is set, "
2303                       "inheriting ssl.* from global scope");
2304                     rc = HANDLER_ERROR;
2305                     continue;
2306                 }
2307                 plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
2308                 *s = *p->ssl_ctxs;/*(copy struct of ssl_ctx from global scope)*/
2309                 continue;
2310             }
2311             /* PEM file is required */
2312             log_error(srv->errh, __FILE__, __LINE__,
2313               "ssl.pemfile has to be set when ssl.engine = \"enable\"");
2314             rc = HANDLER_ERROR;
2315             continue;
2316         }
2317 
2318         /* configure ssl_ctx for socket */
2319 
2320         /*conf.ssl_ctx = NULL;*//*(filled by network_init_ssl() even on error)*/
2321         if (0 == network_init_ssl(srv, &conf, p)) {
2322             plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
2323             s->ssl_ctx = conf.ssl_ctx;
2324         }
2325         else {
2326             SSL_CTX_free(conf.ssl_ctx);
2327             rc = HANDLER_ERROR;
2328         }
2329     }
2330 
2331   #ifdef HAVE_SESSION_TICKET
2332     if (rc == HANDLER_GO_ON && ssl_is_init)
2333         mod_openssl_session_ticket_key_check(p, log_epoch_secs);
2334   #endif
2335 
2336     free(srvplug.cvlist);
2337     return rc;
2338 }
2339 
2340 
2341 SETDEFAULTS_FUNC(mod_openssl_set_defaults)
2342 {
2343     static const config_plugin_keys_t cpk[] = {
2344       { CONST_STR_LEN("ssl.pemfile"),
2345         T_CONFIG_STRING,
2346         T_CONFIG_SCOPE_CONNECTION }
2347      ,{ CONST_STR_LEN("ssl.privkey"),
2348         T_CONFIG_STRING,
2349         T_CONFIG_SCOPE_CONNECTION }
2350      ,{ CONST_STR_LEN("ssl.ca-file"),
2351         T_CONFIG_STRING,
2352         T_CONFIG_SCOPE_CONNECTION }
2353      ,{ CONST_STR_LEN("ssl.ca-dn-file"),
2354         T_CONFIG_STRING,
2355         T_CONFIG_SCOPE_CONNECTION }
2356      ,{ CONST_STR_LEN("ssl.ca-crl-file"),
2357         T_CONFIG_STRING,
2358         T_CONFIG_SCOPE_CONNECTION }
2359      ,{ CONST_STR_LEN("ssl.read-ahead"),
2360         T_CONFIG_BOOL,
2361         T_CONFIG_SCOPE_CONNECTION }
2362      ,{ CONST_STR_LEN("ssl.disable-client-renegotiation"),
2363         T_CONFIG_BOOL,
2364         T_CONFIG_SCOPE_CONNECTION }
2365      ,{ CONST_STR_LEN("ssl.verifyclient.activate"),
2366         T_CONFIG_BOOL,
2367         T_CONFIG_SCOPE_CONNECTION }
2368      ,{ CONST_STR_LEN("ssl.verifyclient.enforce"),
2369         T_CONFIG_BOOL,
2370         T_CONFIG_SCOPE_CONNECTION }
2371      ,{ CONST_STR_LEN("ssl.verifyclient.depth"),
2372         T_CONFIG_SHORT,
2373         T_CONFIG_SCOPE_CONNECTION }
2374      ,{ CONST_STR_LEN("ssl.verifyclient.username"),
2375         T_CONFIG_STRING,
2376         T_CONFIG_SCOPE_CONNECTION }
2377      ,{ CONST_STR_LEN("ssl.verifyclient.exportcert"),
2378         T_CONFIG_BOOL,
2379         T_CONFIG_SCOPE_CONNECTION }
2380      ,{ CONST_STR_LEN("ssl.acme-tls-1"),
2381         T_CONFIG_STRING,
2382         T_CONFIG_SCOPE_CONNECTION }
2383      ,{ CONST_STR_LEN("ssl.stapling-file"),
2384         T_CONFIG_STRING,
2385         T_CONFIG_SCOPE_CONNECTION }
2386      ,{ CONST_STR_LEN("debug.log-ssl-noise"),
2387         T_CONFIG_BOOL,
2388         T_CONFIG_SCOPE_CONNECTION }
2389      ,{ NULL, 0,
2390         T_CONFIG_UNSET,
2391         T_CONFIG_SCOPE_UNSET }
2392     };
2393 
2394     plugin_data * const p = p_d;
2395     p->srv = srv;
2396     p->cafiles = array_init(0);
2397     if (!config_plugin_values_init(srv, p, cpk, "mod_openssl"))
2398         return HANDLER_ERROR;
2399 
2400     const buffer *default_ssl_ca_crl_file = NULL;
2401 
2402     /* process and validate config directives
2403      * (init i to 0 if global context; to 1 to skip empty global context) */
2404     for (int i = !p->cvlist[0].v.u2[1]; i < p->nconfig; ++i) {
2405         config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
2406         config_plugin_value_t *pemfile = NULL;
2407         config_plugin_value_t *privkey = NULL;
2408         const buffer *ssl_stapling_file = NULL;
2409         const buffer *ssl_ca_file = NULL;
2410         const buffer *ssl_ca_dn_file = NULL;
2411         const buffer *ssl_ca_crl_file = NULL;
2412         X509_STORE *ca_store = NULL;
2413         for (; -1 != cpv->k_id; ++cpv) {
2414             switch (cpv->k_id) {
2415               case 0: /* ssl.pemfile */
2416                 if (!buffer_string_is_empty(cpv->v.b)) pemfile = cpv;
2417                 break;
2418               case 1: /* ssl.privkey */
2419                 if (!buffer_string_is_empty(cpv->v.b)) privkey = cpv;
2420                 break;
2421               case 2: /* ssl.ca-file */
2422                 if (buffer_string_is_empty(cpv->v.b)) break;
2423                 if (!mod_openssl_init_once_openssl(srv)) return HANDLER_ERROR;
2424                 ssl_ca_file = cpv->v.b;
2425                 cpv->v.v = mod_wolfssl_load_cacerts(ssl_ca_file, srv->errh);
2426                 if (NULL != cpv->v.v) {
2427                     cpv->vtype = T_CONFIG_LOCAL;
2428                     ca_store = ((plugin_cacerts *)cpv->v.v)->certs;
2429                 }
2430                 else {
2431                     log_error(srv->errh, __FILE__, __LINE__, "SSL: %s %s",
2432                       ERR_error_string(ERR_get_error(), NULL),
2433                       ssl_ca_file->ptr);
2434                     return HANDLER_ERROR;
2435                 }
2436                 break;
2437               case 3: /* ssl.ca-dn-file */
2438                 if (buffer_string_is_empty(cpv->v.b)) break;
2439                 if (!mod_openssl_init_once_openssl(srv)) return HANDLER_ERROR;
2440                 ssl_ca_dn_file = cpv->v.b;
2441                #ifndef OPENSSL_ALL
2442                 {
2443                     log_error(srv->errh, __FILE__, __LINE__,
2444                       "SSL: You specified ssl.ca-dn-file "
2445                       "but wolfssl library built without necessary support");
2446                     return HANDLER_ERROR;
2447                 }
2448                #endif
2449                 cpv->v.v = mod_wolfssl_load_client_CA_file(ssl_ca_dn_file,
2450                                                            srv->errh);
2451                 if (NULL != cpv->v.v) {
2452                     cpv->vtype = T_CONFIG_LOCAL;
2453                 }
2454                 else {
2455                     log_error(srv->errh, __FILE__, __LINE__, "SSL: %s %s",
2456                       ERR_error_string(ERR_get_error(), NULL),
2457                       ssl_ca_dn_file->ptr);
2458                     return HANDLER_ERROR;
2459                 }
2460                 break;
2461               case 4: /* ssl.ca-crl-file */
2462                 if (buffer_string_is_empty(cpv->v.b)) break;
2463                 ssl_ca_crl_file = cpv->v.b;
2464                 if (0 == i) default_ssl_ca_crl_file = cpv->v.b;
2465                 break;
2466               case 5: /* ssl.read-ahead */
2467               case 6: /* ssl.disable-client-renegotiation */
2468               case 7: /* ssl.verifyclient.activate */
2469               case 8: /* ssl.verifyclient.enforce */
2470                 break;
2471               case 9: /* ssl.verifyclient.depth */
2472                 if (cpv->v.shrt > 255) {
2473                     log_error(srv->errh, __FILE__, __LINE__,
2474                       "%s is absurdly large (%hu); limiting to 255",
2475                       cpk[cpv->k_id].k, cpv->v.shrt);
2476                     cpv->v.shrt = 255;
2477                 }
2478                 break;
2479               case 10:/* ssl.verifyclient.username */
2480               case 11:/* ssl.verifyclient.exportcert */
2481               case 12:/* ssl.acme-tls-1 */
2482                 break;
2483               case 13:/* ssl.stapling-file */
2484                 ssl_stapling_file = cpv->v.b;
2485                 break;
2486               case 14:/* debug.log-ssl-noise */
2487                 break;
2488               default:/* should not happen */
2489                 break;
2490             }
2491         }
2492 
2493         /* p->cafiles for legacy only */
2494         /* load all ssl.ca-files into a single chain */
2495         /*(certificate load order might matter)*/
2496         if (ssl_ca_dn_file)
2497             array_insert_value(p->cafiles, CONST_BUF_LEN(ssl_ca_dn_file));
2498         if (ssl_ca_file)
2499             array_insert_value(p->cafiles, CONST_BUF_LEN(ssl_ca_file));
2500         UNUSED(ca_store);
2501         UNUSED(ssl_ca_crl_file);
2502         UNUSED(default_ssl_ca_crl_file);
2503 
2504         if (pemfile) {
2505           #ifndef HAVE_TLS_EXTENSIONS
2506             config_cond_info cfginfo;
2507             uint32_t j = (uint32_t)p->cvlist[i].k_id;
2508             config_get_config_cond_info(&cfginfo, j);
2509             if (j > 0 && (COMP_SERVER_SOCKET != cfginfo.comp
2510                           || cfginfo.cond != CONFIG_COND_EQ)) {
2511                 if (COMP_HTTP_HOST == cfginfo.comp)
2512                     log_error(srv->errh, __FILE__, __LINE__, "SSL:"
2513                       "can't use ssl.pemfile with $HTTP[\"host\"], "
2514                       "as openssl version does not support TLS extensions");
2515                 else
2516                     log_error(srv->errh, __FILE__, __LINE__, "SSL:"
2517                       "ssl.pemfile only works in SSL socket binding context "
2518                       "as openssl version does not support TLS extensions");
2519                 return HANDLER_ERROR;
2520             }
2521           #endif
2522             if (NULL == privkey) privkey = pemfile;
2523             pemfile->v.v =
2524               network_openssl_load_pemfile(srv, pemfile->v.b, privkey->v.b,
2525                                            ssl_stapling_file);
2526             if (pemfile->v.v)
2527                 pemfile->vtype = T_CONFIG_LOCAL;
2528             else
2529                 return HANDLER_ERROR;
2530         }
2531     }
2532 
2533     p->defaults.ssl_verifyclient = 0;
2534     p->defaults.ssl_verifyclient_enforce = 1;
2535     p->defaults.ssl_verifyclient_depth = 9;
2536     p->defaults.ssl_verifyclient_export_cert = 0;
2537     p->defaults.ssl_disable_client_renegotiation = 1;
2538     p->defaults.ssl_read_ahead = 0;
2539 
2540     /* initialize p->defaults from global config context */
2541     if (p->nconfig > 0 && p->cvlist->v.u2[1]) {
2542         const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0];
2543         if (-1 != cpv->k_id)
2544             mod_openssl_merge_config(&p->defaults, cpv);
2545     }
2546 
2547     return mod_openssl_set_defaults_sockets(srv, p);
2548 }
2549 
2550 
2551     /* local_send_buffer is a static buffer of size (LOCAL_SEND_BUFSIZE)
2552      *
2553      * it has to stay at the same location all the time to satisfy the needs
2554      * of SSL_write to pass the SAME parameter in case of a _WANT_WRITE
2555      *
2556      * buffer is allocated once, is NOT realloced (note: not thread-safe)
2557      *
2558      * (Note: above restriction no longer true since SSL_CTX_set_mode() is
2559      *        called with SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)
2560      * */
2561 
2562             /* copy small mem chunks into single large buffer before SSL_write()
2563              * to reduce number times write() called underneath SSL_write() and
2564              * potentially reduce number of packets generated if TCP_NODELAY */
2565 
2566 
2567 static int
2568 mod_openssl_close_notify(handler_ctx *hctx);
2569 
2570 
2571 static int
2572 connection_write_cq_ssl (connection *con, chunkqueue *cq, off_t max_bytes)
2573 {
2574     handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id];
2575     SSL *ssl = hctx->ssl;
2576     log_error_st * const errh = hctx->errh;
2577 
2578     if (0 != hctx->close_notify) return mod_openssl_close_notify(hctx);
2579 
2580     chunkqueue_remove_finished_chunks(cq);
2581 
2582     while (max_bytes > 0 && !chunkqueue_is_empty(cq)) {
2583         char *data = local_send_buffer;
2584         uint32_t data_len = LOCAL_SEND_BUFSIZE < max_bytes
2585           ? LOCAL_SEND_BUFSIZE
2586           : (uint32_t)max_bytes;
2587         int wr;
2588 
2589         if (0 != chunkqueue_peek_data(cq, &data, &data_len, errh)) return -1;
2590 
2591         /**
2592          * SSL_write man-page
2593          *
2594          * WARNING
2595          *        When an SSL_write() operation has to be repeated because of
2596          *        SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be
2597          *        repeated with the same arguments.
2598          */
2599 
2600         ERR_clear_error();
2601         wr = SSL_write(ssl, data, data_len);
2602 
2603         if (hctx->renegotiations > 1
2604             && hctx->conf.ssl_disable_client_renegotiation) {
2605             log_error(errh, __FILE__, __LINE__,
2606               "SSL: renegotiation initiated by client, killing connection");
2607             return -1;
2608         }
2609 
2610         if (wr <= 0) {
2611             int ssl_r;
2612             unsigned long err;
2613 
2614             switch ((ssl_r = SSL_get_error(ssl, wr))) {
2615             case SSL_ERROR_WANT_READ:
2616                 con->is_readable = -1;
2617                 return 0; /* try again later */
2618             case SSL_ERROR_WANT_WRITE:
2619                 con->is_writable = -1;
2620                 return 0; /* try again later */
2621             case SSL_ERROR_SYSCALL:
2622                 /* perhaps we have error waiting in our error-queue */
2623                 if (0 != (err = ERR_get_error())) {
2624                     do {
2625                         log_error(errh, __FILE__, __LINE__,
2626                           "SSL: %d %d %s",ssl_r,wr,ERR_error_string(err,NULL));
2627                     } while((err = ERR_get_error()));
2628                 } else if (wr == -1) {
2629                     /* no, but we have errno */
2630                     switch(errno) {
2631                     case EPIPE:
2632                     case ECONNRESET:
2633                         return -2;
2634                     default:
2635                         log_perror(errh, __FILE__, __LINE__,
2636                           "SSL: %d %d", ssl_r, wr);
2637                         break;
2638                     }
2639                 } else {
2640                     /* neither error-queue nor errno ? */
2641                     log_perror(errh, __FILE__, __LINE__,
2642                       "SSL (error): %d %d", ssl_r, wr);
2643                 }
2644                 break;
2645 
2646             case SSL_ERROR_ZERO_RETURN:
2647                 /* clean shutdown on the remote side */
2648 
2649                 if (wr == 0) return -2;
2650 
2651                 /* fall through */
2652             default:
2653                 while((err = ERR_get_error())) {
2654                     log_error(errh, __FILE__, __LINE__,
2655                       "SSL: %d %d %s", ssl_r, wr, ERR_error_string(err, NULL));
2656                 }
2657                 break;
2658             }
2659             return -1;
2660         }
2661 
2662         chunkqueue_mark_written(cq, wr);
2663         max_bytes -= wr;
2664 
2665         if ((size_t) wr < data_len) break; /* try again later */
2666     }
2667 
2668     return 0;
2669 }
2670 
2671 
2672 static int
2673 connection_read_cq_ssl (connection *con, chunkqueue *cq, off_t max_bytes)
2674 {
2675     handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id];
2676     int len;
2677     char *mem = NULL;
2678     size_t mem_len = 0;
2679 
2680     UNUSED(max_bytes);
2681 
2682     if (0 != hctx->close_notify) return mod_openssl_close_notify(hctx);
2683 
2684     ERR_clear_error();
2685     do {
2686         len = SSL_pending(hctx->ssl);
2687         mem_len = len < 2048 ? 2048 : (size_t)len;
2688         chunk * const ckpt = cq->last;
2689         mem = chunkqueue_get_memory(cq, &mem_len);
2690 
2691         len = SSL_read(hctx->ssl, mem, mem_len);
2692         if (len > 0) {
2693             chunkqueue_use_memory(cq, ckpt, len);
2694             con->bytes_read += len;
2695         } else {
2696             chunkqueue_use_memory(cq, ckpt, 0);
2697         }
2698 
2699         if (hctx->renegotiations > 1
2700             && hctx->conf.ssl_disable_client_renegotiation) {
2701             log_error(hctx->errh, __FILE__, __LINE__,
2702               "SSL: renegotiation initiated by client, killing connection");
2703             return -1;
2704         }
2705 
2706       #ifdef HAVE_ALPN
2707       #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2708         if (hctx->alpn) {
2709             if (hctx->alpn == MOD_OPENSSL_ALPN_ACME_TLS_1) {
2710                 chunkqueue_reset(cq);
2711                 /* initiate handshake in order to send ServerHello.
2712                  * Once TLS handshake is complete, return -1 to result in
2713                  * CON_STATE_ERROR so that socket connection is quickly closed*/
2714                 if (1 == SSL_do_handshake(hctx->ssl)) return -1;
2715                 len = -1;
2716                 break;
2717             }
2718             hctx->alpn = 0;
2719         }
2720       #endif
2721       #endif
2722     } while (len > 0
2723              && (hctx->conf.ssl_read_ahead || SSL_pending(hctx->ssl) > 0));
2724 
2725     if (len < 0) {
2726         int oerrno = errno;
2727         int rc, ssl_err;
2728         switch ((rc = SSL_get_error(hctx->ssl, len))) {
2729         case SSL_ERROR_WANT_WRITE:
2730             con->is_writable = -1;
2731             /* fall through */
2732         case SSL_ERROR_WANT_READ:
2733             con->is_readable = 0;
2734 
2735             /* the manual says we have to call SSL_read with the same arguments
2736              * next time.  we ignore this restriction; no one has complained
2737              * about it in 1.5 yet, so it probably works anyway.
2738              */
2739 
2740             return 0;
2741         case SSL_ERROR_SYSCALL:
2742             /**
2743              * man SSL_get_error()
2744              *
2745              * SSL_ERROR_SYSCALL
2746              *   Some I/O error occurred.  The OpenSSL error queue may contain
2747              *   more information on the error.  If the error queue is empty
2748              *   (i.e. ERR_get_error() returns 0), ret can be used to find out
2749              *   more about the error: If ret == 0, an EOF was observed that
2750              *   violates the protocol.  If ret == -1, the underlying BIO
2751              *   reported an I/O error (for socket I/O on Unix systems, consult
2752              *   errno for details).
2753              *
2754              */
2755             while((ssl_err = ERR_get_error())) {
2756                 /* get all errors from the error-queue */
2757                 log_error(hctx->errh, __FILE__, __LINE__,
2758                   "SSL: %d %s", rc, ERR_error_string(ssl_err, NULL));
2759             }
2760 
2761             switch(oerrno) {
2762             case ECONNRESET:
2763                 if (!hctx->conf.ssl_log_noise) break;
2764                 /* fall through */
2765             default:
2766                 /* (oerrno should be something like ECONNABORTED not 0
2767                  *  if client disconnected before anything was sent
2768                  *  (e.g. TCP connection probe), but it does not appear
2769                  *  that openssl provides such notification, not even
2770                  *  something like SSL_R_SSL_HANDSHAKE_FAILURE) */
2771                 if (0==oerrno && 0==cq->bytes_in && !hctx->conf.ssl_log_noise)
2772                     break;
2773 
2774                 log_error(hctx->errh, __FILE__, __LINE__,
2775                   "SSL: %d %d %d %s", len, rc, oerrno, strerror(oerrno));
2776                 break;
2777             }
2778 
2779             break;
2780         case SSL_ERROR_ZERO_RETURN:
2781             /* clean shutdown on the remote side */
2782 
2783             if (rc == 0) {
2784                 /* FIXME: later */
2785             }
2786 
2787             /* fall through */
2788         default:
2789             while((ssl_err = ERR_get_error())) {
2790                 switch (ERR_GET_REASON(ssl_err)) {
2791                 case SSL_R_SSL_HANDSHAKE_FAILURE:
2792               #ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING
2793                 case SSL_R_UNEXPECTED_EOF_WHILE_READING:
2794               #endif
2795               #ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
2796                 case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
2797               #endif
2798               #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
2799                 case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
2800               #endif
2801               #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
2802                 case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
2803               #endif
2804                     if (!hctx->conf.ssl_log_noise) continue;
2805                     break;
2806                 default:
2807                     break;
2808                 }
2809                 /* get all errors from the error-queue */
2810                 log_error(hctx->errh, __FILE__, __LINE__,
2811                   "SSL: %d %s", rc, ERR_error_string(ssl_err, NULL));
2812             }
2813             break;
2814         }
2815         return -1;
2816     } else if (len == 0) {
2817         con->is_readable = 0;
2818         /* the other end close the connection -> KEEP-ALIVE */
2819 
2820         return -2;
2821     } else {
2822         return 0;
2823     }
2824 }
2825 
2826 
2827 CONNECTION_FUNC(mod_openssl_handle_con_accept)
2828 {
2829     server_socket *srv_sock = con->srv_socket;
2830     if (!srv_sock->is_ssl) return HANDLER_GO_ON;
2831 
2832     plugin_data *p = p_d;
2833     handler_ctx * const hctx = handler_ctx_init();
2834     request_st * const r = &con->request;
2835     hctx->r = r;
2836     hctx->con = con;
2837     hctx->tmp_buf = con->srv->tmp_buf;
2838     hctx->errh = r->conf.errh;
2839     con->plugin_ctx[p->id] = hctx;
2840 
2841     plugin_ssl_ctx * const s = p->ssl_ctxs + srv_sock->sidx;
2842     hctx->ssl = SSL_new(s->ssl_ctx);
2843     if (NULL != hctx->ssl
2844         && SSL_set_app_data(hctx->ssl, hctx)
2845         && SSL_set_fd(hctx->ssl, con->fd)) {
2846         SSL_set_accept_state(hctx->ssl);
2847         con->network_read = connection_read_cq_ssl;
2848         con->network_write = connection_write_cq_ssl;
2849         con->proto_default_port = 443; /* "https" */
2850         mod_openssl_patch_config(r, &hctx->conf);
2851         return HANDLER_GO_ON;
2852     }
2853     else {
2854         log_error(r->conf.errh, __FILE__, __LINE__,
2855           "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
2856         return HANDLER_ERROR;
2857     }
2858 }
2859 
2860 
2861 static void
2862 mod_openssl_detach(handler_ctx *hctx)
2863 {
2864     /* step aside from further SSL processing
2865      * (used after handle_connection_shut_wr hook) */
2866     /* future: might restore prior network_read and network_write fn ptrs */
2867     hctx->con->is_ssl_sock = 0;
2868     /* if called after handle_connection_shut_wr hook, shutdown SHUT_WR */
2869     if (-1 == hctx->close_notify) shutdown(hctx->con->fd, SHUT_WR);
2870     hctx->close_notify = 1;
2871 }
2872 
2873 
2874 CONNECTION_FUNC(mod_openssl_handle_con_shut_wr)
2875 {
2876     plugin_data *p = p_d;
2877     handler_ctx *hctx = con->plugin_ctx[p->id];
2878     if (NULL == hctx) return HANDLER_GO_ON;
2879 
2880     hctx->close_notify = -2;
2881     if (SSL_is_init_finished(hctx->ssl)) {
2882         mod_openssl_close_notify(hctx);
2883     }
2884     else {
2885         mod_openssl_detach(hctx);
2886     }
2887 
2888     return HANDLER_GO_ON;
2889 }
2890 
2891 
2892 static int
2893 mod_openssl_close_notify(handler_ctx *hctx)
2894 {
2895         int ret, ssl_r;
2896         unsigned long err;
2897         log_error_st *errh;
2898 
2899         if (1 == hctx->close_notify) return -2;
2900 
2901         ERR_clear_error();
2902         switch ((ret = SSL_shutdown(hctx->ssl))) {
2903         case 1:
2904             mod_openssl_detach(hctx);
2905             return -2;
2906         case 0:
2907             /* Drain SSL read buffers in case pending records need processing.
2908              * Limit to reading next record to avoid denial of service when CPU
2909              * processing TLS is slower than arrival speed of TLS data packets.
2910              * (unless hctx->conf.ssl_read_ahead is set)
2911              *
2912              * references:
2913              *
2914              * "New session ticket breaks bidirectional shutdown of TLS 1.3 connection"
2915              * https://github.com/openssl/openssl/issues/6262
2916              *
2917              * The peer is still allowed to send data after receiving the
2918              * "close notify" event. If the peer did send data it need to be
2919              * processed by calling SSL_read() before calling SSL_shutdown() a
2920              * second time. SSL_read() will indicate the end of the peer data by
2921              * returning <= 0 and SSL_get_error() returning
2922              * SSL_ERROR_ZERO_RETURN. It is recommended to call SSL_read()
2923              * between SSL_shutdown() calls.
2924              *
2925              * Additional discussion in "Auto retry in shutdown"
2926              * https://github.com/openssl/openssl/pull/6340
2927              */
2928             ssl_r = SSL_pending(hctx->ssl);
2929             if (ssl_r) {
2930                 do {
2931                     char buf[4096];
2932                     ret = SSL_read(hctx->ssl, buf, (int)sizeof(buf));
2933                 } while (ret > 0 && (hctx->conf.ssl_read_ahead||(ssl_r-=ret)));
2934             }
2935 
2936             ERR_clear_error();
2937             switch ((ret = SSL_shutdown(hctx->ssl))) {
2938             case 1:
2939                 mod_openssl_detach(hctx);
2940                 return -2;
2941             case 0:
2942                 hctx->close_notify = -1;
2943                 return 0;
2944             default:
2945                 break;
2946             }
2947 
2948             /* fall through */
2949         default:
2950 
2951             if (!SSL_is_init_finished(hctx->ssl)) {
2952                 mod_openssl_detach(hctx);
2953                 return -2;
2954             }
2955 
2956             switch ((ssl_r = SSL_get_error(hctx->ssl, ret))) {
2957             case SSL_ERROR_ZERO_RETURN:
2958             case SSL_ERROR_WANT_WRITE:
2959             case SSL_ERROR_WANT_READ:
2960                 hctx->close_notify = -1;
2961                 return 0; /* try again later */
2962             case SSL_ERROR_SYSCALL:
2963                 /* perhaps we have error waiting in our error-queue */
2964                 errh = hctx->r->conf.errh;
2965                 if (0 != (err = ERR_get_error())) {
2966                     do {
2967                         log_error(errh, __FILE__, __LINE__,
2968                           "SSL: %d %d %s",ssl_r,ret,ERR_error_string(err,NULL));
2969                     } while((err = ERR_get_error()));
2970                 } else if (errno != 0) {
2971                     /*ssl bug (see lighttpd ticket #2213): sometimes errno==0*/
2972                     switch(errno) {
2973                     case EPIPE:
2974                     case ECONNRESET:
2975                         break;
2976                     default:
2977                         log_perror(errh, __FILE__, __LINE__,
2978                           "SSL (error): %d %d", ssl_r, ret);
2979                         break;
2980                     }
2981                 }
2982 
2983                 break;
2984             default:
2985                 errh = hctx->r->conf.errh;
2986                 while((err = ERR_get_error())) {
2987                     log_error(errh, __FILE__, __LINE__,
2988                       "SSL: %d %d %s", ssl_r, ret, ERR_error_string(err, NULL));
2989                 }
2990 
2991                 break;
2992             }
2993         }
2994         ERR_clear_error();
2995         hctx->close_notify = -1;
2996         return ret;
2997 }
2998 
2999 
3000 CONNECTION_FUNC(mod_openssl_handle_con_close)
3001 {
3002     plugin_data *p = p_d;
3003     handler_ctx *hctx = con->plugin_ctx[p->id];
3004     if (NULL != hctx) {
3005         con->plugin_ctx[p->id] = NULL;
3006         handler_ctx_free(hctx);
3007     }
3008 
3009     return HANDLER_GO_ON;
3010 }
3011 
3012 
3013 static void
3014 https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
3015 {
3016     buffer * const tb = r->tmp_buf;
3017     X509 *xs;
3018     X509_NAME *xn;
3019     int i, nentries;
3020 
3021     long vr = SSL_get_verify_result(hctx->ssl);
3022     if (vr != X509_V_OK) {
3023         char errstr[256];
3024         ERR_error_string_n(vr, errstr, sizeof(errstr));
3025         buffer_copy_string_len(tb, CONST_STR_LEN("FAILED:"));
3026         buffer_append_string(tb, errstr);
3027         http_header_env_set(r,
3028                             CONST_STR_LEN("SSL_CLIENT_VERIFY"),
3029                             CONST_BUF_LEN(tb));
3030         return;
3031     } else if (!(xs = SSL_get_peer_certificate(hctx->ssl))) {
3032         http_header_env_set(r,
3033                             CONST_STR_LEN("SSL_CLIENT_VERIFY"),
3034                             CONST_STR_LEN("NONE"));
3035         return;
3036     } else {
3037         http_header_env_set(r,
3038                             CONST_STR_LEN("SSL_CLIENT_VERIFY"),
3039                             CONST_STR_LEN("SUCCESS"));
3040     }
3041 
3042     xn = X509_get_subject_name(xs);
3043     {
3044         char buf[256];
3045         int len = safer_X509_NAME_oneline(xn, buf, sizeof(buf));
3046         if (len > 0) {
3047             if (len >= (int)sizeof(buf)) len = (int)sizeof(buf)-1;
3048             http_header_env_set(r,
3049                                 CONST_STR_LEN("SSL_CLIENT_S_DN"),
3050                                 buf, (size_t)len);
3051         }
3052     }
3053     buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
3054     for (i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
3055         int xobjnid;
3056         const char * xobjsn;
3057         X509_NAME_ENTRY *xe;
3058 
3059         if (!(xe = wolfSSL_X509_NAME_get_entry(xn, i))) {
3060             continue;
3061         }
3062         xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
3063         xobjsn = OBJ_nid2sn(xobjnid);
3064         if (xobjsn) {
3065             buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
3066             buffer_append_string(tb, xobjsn);
3067             http_header_env_set(r,
3068                                 CONST_BUF_LEN(tb),
3069                                 (const char*)X509_NAME_ENTRY_get_data(xe)->data,
3070                                 X509_NAME_ENTRY_get_data(xe)->length);
3071         }
3072     }
3073 
3074     {
3075         byte buf[64];
3076         int bsz = (int)sizeof(buf);
3077         if (wolfSSL_X509_get_serial_number(xs, buf, &bsz) == WOLFSSL_SUCCESS) {
3078             char serialHex[128+1];
3079             li_tohex_uc(serialHex, sizeof(serialHex), (char *)buf, (size_t)bsz);
3080             http_header_env_set(r,
3081                                 CONST_STR_LEN("SSL_CLIENT_M_SERIAL"),
3082                                 serialHex, strlen(serialHex));
3083         }
3084     }
3085 
3086     if (!buffer_string_is_empty(hctx->conf.ssl_verifyclient_username)) {
3087         /* pick one of the exported values as "REMOTE_USER", for example
3088          *   ssl.verifyclient.username = "SSL_CLIENT_S_DN_UID"
3089          * or
3090          *   ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
3091          */
3092         const buffer *varname = hctx->conf.ssl_verifyclient_username;
3093         const buffer *vb = http_header_env_get(r, CONST_BUF_LEN(varname));
3094         if (vb) { /* same as http_auth.c:http_auth_setenv() */
3095             http_header_env_set(r,
3096                                 CONST_STR_LEN("REMOTE_USER"),
3097                                 CONST_BUF_LEN(vb));
3098             http_header_env_set(r,
3099                                 CONST_STR_LEN("AUTH_TYPE"),
3100                                 CONST_STR_LEN("SSL_CLIENT_VERIFY"));
3101         }
3102     }
3103 
3104     if (hctx->conf.ssl_verifyclient_export_cert) {
3105         int dersz, pemsz;
3106         const unsigned char *der = wolfSSL_X509_get_der(xs, &dersz);
3107         pemsz = der ? wc_DerToPemEx(der, dersz, NULL, 0, NULL, CERT_TYPE) : 0;
3108         if (pemsz > 0) {
3109             buffer_string_prepare_copy(tb, pemsz);
3110             if (0 == wc_DerToPemEx(der, dersz, (byte *)tb->ptr, pemsz,
3111                                    NULL, CERT_TYPE))
3112                 http_header_env_set(r,
3113                                     CONST_STR_LEN("SSL_CLIENT_CERT"),
3114                                     tb->ptr, (uint32_t)pemsz);
3115         }
3116     }
3117     X509_free(xs);
3118 }
3119 
3120 
3121 static void
3122 http_cgi_ssl_env (request_st * const r, handler_ctx * const hctx)
3123 {
3124     const char *s;
3125     const SSL_CIPHER *cipher;
3126 
3127     s = SSL_get_version(hctx->ssl);
3128     http_header_env_set(r, CONST_STR_LEN("SSL_PROTOCOL"), s, strlen(s));
3129 
3130     if ((cipher = SSL_get_current_cipher(hctx->ssl))) {
3131         s = SSL_CIPHER_get_name(cipher);
3132         http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER"), s, strlen(s));
3133         /*(wolfSSL preprocessor defines are obnoxious)*/
3134       #if defined(OPENSSL_ALL) \
3135        || (defined(OPENSSL_EXTRA) \
3136            && (defined(HAVE_STUNNEL)    || \
3137                defined(WOLFSSL_NGINX)   || defined(HAVE_LIGHTY) || \
3138                defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
3139         int usekeysize, algkeysize = 0;
3140         char buf[LI_ITOSTRING_LENGTH];
3141         usekeysize = wolfSSL_CIPHER_get_bits(cipher, &algkeysize);
3142         if (0 == algkeysize) algkeysize = usekeysize;
3143         http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER_USEKEYSIZE"),
3144                             buf, li_itostrn(buf, sizeof(buf), usekeysize));
3145         http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER_ALGKEYSIZE"),
3146                             buf, li_itostrn(buf, sizeof(buf), algkeysize));
3147       #endif
3148     }
3149 }
3150 
3151 
3152 REQUEST_FUNC(mod_openssl_handle_request_env)
3153 {
3154     plugin_data *p = p_d;
3155     /* simple flag for request_env_patched */
3156     if (r->plugin_ctx[p->id]) return HANDLER_GO_ON;
3157     handler_ctx *hctx = r->con->plugin_ctx[p->id];
3158     if (NULL == hctx) return HANDLER_GO_ON;
3159     r->plugin_ctx[p->id] = (void *)(uintptr_t)1u;
3160 
3161     http_cgi_ssl_env(r, hctx);
3162     if (hctx->conf.ssl_verifyclient) {
3163         https_add_ssl_client_entries(r, hctx);
3164     }
3165 
3166     return HANDLER_GO_ON;
3167 }
3168 
3169 
3170 REQUEST_FUNC(mod_openssl_handle_uri_raw)
3171 {
3172     /* mod_openssl must be loaded prior to mod_auth
3173      * if mod_openssl is configured to set REMOTE_USER based on client cert */
3174     /* mod_openssl must be loaded after mod_extforward
3175      * if mod_openssl config is based on lighttpd.conf remote IP conditional
3176      * using remote IP address set by mod_extforward, *unless* PROXY protocol
3177      * is enabled with extforward.hap-PROXY = "enable", in which case the
3178      * reverse is true: mod_extforward must be loaded after mod_openssl */
3179     plugin_data *p = p_d;
3180     handler_ctx *hctx = r->con->plugin_ctx[p->id];
3181     if (NULL == hctx) return HANDLER_GO_ON;
3182 
3183     mod_openssl_patch_config(r, &hctx->conf);
3184     if (hctx->conf.ssl_verifyclient) {
3185         mod_openssl_handle_request_env(r, p);
3186     }
3187 
3188     return HANDLER_GO_ON;
3189 }
3190 
3191 
3192 REQUEST_FUNC(mod_openssl_handle_request_reset)
3193 {
3194     plugin_data *p = p_d;
3195     r->plugin_ctx[p->id] = NULL; /* simple flag for request_env_patched */
3196     return HANDLER_GO_ON;
3197 }
3198 
3199 
3200 TRIGGER_FUNC(mod_openssl_handle_trigger) {
3201     const plugin_data * const p = p_d;
3202     const time_t cur_ts = log_epoch_secs;
3203     if (cur_ts & 0x3f) return HANDLER_GO_ON; /*(continue once each 64 sec)*/
3204     UNUSED(srv);
3205     UNUSED(p);
3206 
3207   #ifdef HAVE_SESSION_TICKET
3208     mod_openssl_session_ticket_key_check(p, cur_ts);
3209   #endif
3210 
3211   #ifdef HAVE_OCSP
3212     mod_openssl_refresh_stapling_files(srv, p, cur_ts);
3213   #endif
3214 
3215     return HANDLER_GO_ON;
3216 }
3217 
3218 
3219 int mod_wolfssl_plugin_init (plugin *p);
3220 int mod_wolfssl_plugin_init (plugin *p)
3221 {
3222     p->version      = LIGHTTPD_VERSION_ID;
3223     p->name         = "wolfssl";
3224     p->init         = mod_openssl_init;
3225     p->cleanup      = mod_openssl_free;
3226     p->priv_defaults= mod_openssl_set_defaults;
3227 
3228     p->handle_connection_accept  = mod_openssl_handle_con_accept;
3229     p->handle_connection_shut_wr = mod_openssl_handle_con_shut_wr;
3230     p->handle_connection_close   = mod_openssl_handle_con_close;
3231     p->handle_uri_raw            = mod_openssl_handle_uri_raw;
3232     p->handle_request_env        = mod_openssl_handle_request_env;
3233     p->handle_request_reset      = mod_openssl_handle_request_reset;
3234     p->handle_trigger            = mod_openssl_handle_trigger;
3235 
3236     return 0;
3237 }
3238 
3239 
3240 static int
3241 mod_openssl_ssl_conf_proto_val (server *srv, plugin_config_socket *s, const buffer *b, int max)
3242 {
3243     if (NULL == b) /* default: min TLSv1.2, max TLSv1.3 */
3244       #ifdef TLS1_3_VERSION
3245         return max ? TLS1_3_VERSION : TLS1_2_VERSION;
3246       #else
3247         return TLS1_2_VERSION;
3248       #endif
3249     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("None"))) /*"disable" limit*/
3250         return max
3251           ?
3252            #ifdef TLS1_3_VERSION
3253             TLS1_3_VERSION
3254            #else
3255             TLS1_2_VERSION
3256            #endif
3257           : (s->ssl_use_sslv3 ? SSL3_VERSION : TLS1_VERSION);
3258     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("SSLv3")))
3259         return SSL3_VERSION;
3260     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.0")))
3261         return TLS1_VERSION;
3262     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.1")))
3263         return TLS1_1_VERSION;
3264     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.2")))
3265         return TLS1_2_VERSION;
3266   #ifdef TLS1_3_VERSION
3267     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.3")))
3268         return TLS1_3_VERSION;
3269   #endif
3270     else {
3271         if (buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1"))
3272             || buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1.2")))
3273             log_error(srv->errh, __FILE__, __LINE__,
3274                       "SSL: ssl.openssl.ssl-conf-cmd %s %s ignored",
3275                       max ? "MaxProtocol" : "MinProtocol", b->ptr);
3276         else
3277             log_error(srv->errh, __FILE__, __LINE__,
3278                       "SSL: ssl.openssl.ssl-conf-cmd %s %s invalid; ignored",
3279                       max ? "MaxProtocol" : "MinProtocol", b->ptr);
3280     }
3281   #ifdef TLS1_3_VERSION
3282     return max ? TLS1_3_VERSION : TLS1_2_VERSION;
3283   #else
3284     return TLS1_2_VERSION;
3285   #endif
3286 }
3287 
3288 
3289 static int
3290 mod_openssl_ssl_conf_cmd (server *srv, plugin_config_socket *s)
3291 {
3292     /* reference:
3293      * https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html */
3294     int rc = 0;
3295     buffer *cipherstring = NULL;
3296     /*buffer *ciphersuites = NULL;*/
3297     buffer *minb = NULL;
3298     buffer *maxb = NULL;
3299     buffer *curves = NULL;
3300 
3301     for (size_t i = 0; i < s->ssl_conf_cmd->used; ++i) {
3302         data_string *ds = (data_string *)s->ssl_conf_cmd->data[i];
3303         if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("CipherString")))
3304             cipherstring = &ds->value;
3305       #if 0
3306         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Ciphersuites")))
3307             ciphersuites = &ds->value;
3308       #endif
3309         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Curves"))
3310               || buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Groups")))
3311             curves = &ds->value;
3312         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MaxProtocol")))
3313             maxb = &ds->value;
3314         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MinProtocol")))
3315             minb = &ds->value;
3316         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Protocol"))) {
3317             /* openssl config for Protocol=... is complex and deprecated */
3318             log_error(srv->errh, __FILE__, __LINE__,
3319                       "SSL: ssl.openssl.ssl-conf-cmd %s ignored; "
3320                       "use MinProtocol=... and MaxProtocol=... instead",
3321                       ds->key.ptr);
3322         }
3323         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Options"))) {
3324             for (char *v = ds->value.ptr, *e; *v; v = e) {
3325                 while (*v == ' ' || *v == '\t' || *v == ',') ++v;
3326                 int flag = 1;
3327                 if (*v == '-') {
3328                     flag = 0;
3329                     ++v;
3330                 }
3331                 for (e = v; light_isalpha(*e); ++e) ;
3332                 switch ((int)(e-v)) {
3333                   case 11:
3334                     if (buffer_eq_icase_ssn(v, "Compression", 11)) {
3335                         if (flag)
3336                             SSL_CTX_clear_options(s->ssl_ctx,
3337                                                   SSL_OP_NO_COMPRESSION);
3338                         else
3339                             SSL_CTX_set_options(s->ssl_ctx,
3340                                                 SSL_OP_NO_COMPRESSION);
3341                         continue;
3342                     }
3343                     break;
3344                   case 13:
3345                     if (buffer_eq_icase_ssn(v, "SessionTicket", 13)) {
3346                         if (flag)
3347                             SSL_CTX_clear_options(s->ssl_ctx,
3348                                                   SSL_OP_NO_TICKET);
3349                         else
3350                             SSL_CTX_set_options(s->ssl_ctx,
3351                                                 SSL_OP_NO_TICKET);
3352                         continue;
3353                     }
3354                     break;
3355                   case 16:
3356                     if (buffer_eq_icase_ssn(v, "ServerPreference", 16)) {
3357                         if (flag)
3358                             SSL_CTX_set_options(s->ssl_ctx,
3359                                                SSL_OP_CIPHER_SERVER_PREFERENCE);
3360                         else
3361                             SSL_CTX_clear_options(s->ssl_ctx,
3362                                                SSL_OP_CIPHER_SERVER_PREFERENCE);
3363                         s->ssl_honor_cipher_order = flag;
3364                         continue;
3365                     }
3366                     break;
3367                   default:
3368                     break;
3369                 }
3370                 /* warn if not explicitly handled or ignored above */
3371                 if (!flag) --v;
3372                 log_error(srv->errh, __FILE__, __LINE__,
3373                           "SSL: ssl.openssl.ssl-conf-cmd Options %.*s "
3374                           "ignored", (int)(e-v), v);
3375             }
3376         }
3377       #if 0
3378         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("..."))) {
3379         }
3380       #endif
3381         else {
3382             /* warn if not explicitly handled or ignored above */
3383             log_error(srv->errh, __FILE__, __LINE__,
3384                       "SSL: ssl.openssl.ssl-conf-cmd %s ignored",
3385                       ds->key.ptr);
3386         }
3387 
3388     }
3389 
3390     if (minb) {
3391         int n = mod_openssl_ssl_conf_proto_val(srv, s, minb, 0);
3392         /*(wolfSSL_CTX_SetMinVersion() alt uses enums with different values)*/
3393         switch (n) {
3394           case SSL3_VERSION:   n = WOLFSSL_SSLV3;   break;
3395           case TLS1_VERSION:   n = WOLFSSL_TLSV1;   break;
3396           case TLS1_1_VERSION: n = WOLFSSL_TLSV1_1; break;
3397           case TLS1_2_VERSION: n = WOLFSSL_TLSV1_2; break;
3398           case TLS1_3_VERSION: n = WOLFSSL_TLSV1_3; break;
3399           default: rc = -1; break;
3400         }
3401         if (wolfSSL_CTX_SetMinVersion(s->ssl_ctx, n) != WOLFSSL_SUCCESS)
3402             rc = -1;
3403     }
3404 
3405     if (maxb) {
3406         /* WolfSSL max ver is set at WolfSSL compile-time */
3407     }
3408 
3409     if (!buffer_string_is_empty(cipherstring)) {
3410         /* Disable support for low encryption ciphers */
3411         buffer_append_string_len(cipherstring,
3412                                  CONST_STR_LEN(":!aNULL:!eNULL:!EXP"));
3413         if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
3414             log_error(srv->errh, __FILE__, __LINE__,
3415               "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
3416             rc = -1;
3417         }
3418 
3419         if (s->ssl_honor_cipher_order)
3420             SSL_CTX_set_options(s->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
3421     }
3422 
3423     if (curves) {
3424         if (!mod_openssl_ssl_conf_curves(srv, s, curves))
3425             rc = -1;
3426     }
3427 
3428     return rc;
3429 }
3430