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