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