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