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