lighttpd 1.4.x https://www.lighttpd.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3501 lines
129 KiB

  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. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <errno.h>
  32. #include <fcntl.h>
  33. #include <stdint.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. /*
  37. * Note: mod_wolfssl.c is forked from mod_openssl.c
  38. * Many internal symbol names in mod_wolfssl.c retain the mod_openssl_* prefix
  39. * (wolfSSL provides an OpenSSL compatibility layer)
  40. */
  41. /* wolfSSL needs to be built with ./configure --enable-lighty for lighttpd.
  42. * Doing so defines OPENSSL_EXTRA and HAVE_LIGHTY in <wolfssl/options.h>, and
  43. * these defines are necessary for wolfSSL headers to expose sufficient openssl
  44. * compatibility layer for wolfSSL to be able to provide an openssl substitute
  45. * for use by lighttpd */
  46. /* workaround fragile code in wolfssl/wolfcrypto/types.h */
  47. #if !defined(SIZEOF_LONG) || !defined(SIZEOF_LONG_LONG)
  48. #undef SIZEOF_LONG
  49. #undef SIZEOF_LONG_LONG
  50. #endif
  51. #include <wolfssl/options.h>
  52. #include <wolfssl/ssl.h>
  53. static char global_err_buf[WOLFSSL_MAX_ERROR_SZ];
  54. #undef ERR_error_string
  55. #define ERR_error_string(e,b) \
  56. (wolfSSL_ERR_error_string_n((e),global_err_buf,WOLFSSL_MAX_ERROR_SZ), \
  57. global_err_buf)
  58. #if 0 /* symbols and definitions requires WolfSSL built with -DOPENSSL_EXTRA */
  59. #define SSL_TLSEXT_ERR_OK 0
  60. #define SSL_TLSEXT_ERR_ALERT_FATAL alert_fatal
  61. #define SSL_TLSEXT_ERR_NOACK alert_warning
  62. WOLFSSL_API void wolfSSL_set_verify_depth(WOLFSSL *ssl,int depth);
  63. WOLFSSL_API void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME* name);
  64. WOLFSSL_API int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x, const WOLFSSL_X509_NAME* y);
  65. WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME*);
  66. WOLFSSL_API char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME*, char*, int);
  67. WOLFSSL_API const char* wolfSSL_OBJ_nid2sn(int n);
  68. WOLFSSL_API int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o);
  69. WOLFSSL_API WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne);
  70. WOLFSSL_API WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME *name, int loc);
  71. #endif
  72. #if !defined(OPENSSL_ALL) || LIBWOLFSSL_VERSION_HEX < 0x04002000
  73. /*(invalid; but centralize making these calls no-ops)*/
  74. #define wolfSSL_sk_X509_NAME_num(a) 0
  75. #define wolfSSL_sk_X509_NAME_push(a, b) 0
  76. #define wolfSSL_sk_X509_NAME_pop_free(a, b) do { } while (0)
  77. #define wolfSSL_sk_X509_NAME_free(a) do { } while (0)
  78. #define wolfSSL_X509_get_subject_name(ca) \
  79. ((WOLFSSL_X509_NAME *)1) /* ! NULL */
  80. #define wolfSSL_sk_X509_NAME_new(a) \
  81. ((WOLF_STACK_OF(WOLFSSL_X509_NAME) *)1) /* ! NULL */
  82. #endif
  83. #if LIBWOLFSSL_VERSION_HEX < 0x04006000 || defined(WOLFSSL_NO_FORCE_ZERO)
  84. #define wolfSSL_OPENSSL_cleanse(x,sz) safe_memclear((x),(sz))
  85. #endif
  86. #if LIBWOLFSSL_VERSION_HEX < 0x04002000 /*(exact version needed not checked)*/
  87. #ifndef STACK_OF
  88. #define STACK_OF(x) WOLFSSL_STACK
  89. #endif
  90. #endif
  91. #include "base.h"
  92. #include "fdevent.h"
  93. #include "http_header.h"
  94. #include "http_kv.h"
  95. #include "log.h"
  96. #include "plugin.h"
  97. #include "safe_memclear.h"
  98. typedef struct {
  99. /* SNI per host: with COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
  100. buffer *ssl_pemfile_pkey;
  101. buffer *ssl_pemfile_x509;
  102. buffer **ssl_pemfile_chain;
  103. buffer *ssl_stapling;
  104. const buffer *ssl_pemfile;
  105. const buffer *ssl_privkey;
  106. const buffer *ssl_stapling_file;
  107. time_t ssl_stapling_loadts;
  108. time_t ssl_stapling_nextts;
  109. char must_staple;
  110. } plugin_cert;
  111. typedef struct {
  112. WOLFSSL_CTX *ssl_ctx;
  113. } plugin_ssl_ctx;
  114. typedef struct {
  115. STACK_OF(X509_NAME) *names;
  116. X509_STORE *certs;
  117. } plugin_cacerts;
  118. typedef struct {
  119. WOLFSSL_CTX *ssl_ctx; /* output from network_init_ssl() */
  120. /*(used only during startup; not patched)*/
  121. unsigned char ssl_enabled; /* only interesting for setting up listening sockets. don't use at runtime */
  122. unsigned char ssl_honor_cipher_order; /* determine SSL cipher in server-preferred order, not client-order */
  123. unsigned char ssl_empty_fragments; /* whether to not set SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */
  124. unsigned char ssl_use_sslv2;
  125. unsigned char ssl_use_sslv3;
  126. const buffer *ssl_cipher_list;
  127. const buffer *ssl_dh_file;
  128. const buffer *ssl_ec_curve;
  129. array *ssl_conf_cmd;
  130. /*(copied from plugin_data for socket ssl_ctx config)*/
  131. const plugin_cert *pc;
  132. const plugin_cacerts *ssl_ca_file;
  133. STACK_OF(X509_NAME) *ssl_ca_dn_file;
  134. const buffer *ssl_ca_crl_file;
  135. unsigned char ssl_verifyclient;
  136. unsigned char ssl_verifyclient_enforce;
  137. unsigned char ssl_verifyclient_depth;
  138. unsigned char ssl_read_ahead;
  139. unsigned char ssl_disable_client_renegotiation;
  140. } plugin_config_socket; /*(used at startup during configuration)*/
  141. typedef struct {
  142. /* SNI per host: w/ COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
  143. plugin_cert *pc;
  144. const plugin_cacerts *ssl_ca_file;
  145. STACK_OF(X509_NAME) *ssl_ca_dn_file;
  146. const buffer *ssl_ca_crl_file;
  147. unsigned char ssl_verifyclient;
  148. unsigned char ssl_verifyclient_enforce;
  149. unsigned char ssl_verifyclient_depth;
  150. unsigned char ssl_verifyclient_export_cert;
  151. unsigned char ssl_read_ahead;
  152. unsigned char ssl_log_noise;
  153. unsigned char ssl_disable_client_renegotiation;
  154. const buffer *ssl_verifyclient_username;
  155. const buffer *ssl_acme_tls_1;
  156. } plugin_config;
  157. typedef struct {
  158. PLUGIN_DATA;
  159. plugin_ssl_ctx *ssl_ctxs;
  160. plugin_config defaults;
  161. server *srv;
  162. array *cafiles;
  163. const char *ssl_stek_file;
  164. } plugin_data;
  165. static int ssl_is_init;
  166. /* need assigned p->id for deep access of module handler_ctx for connection
  167. * i.e. handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id]; */
  168. static plugin_data *plugin_data_singleton;
  169. #define LOCAL_SEND_BUFSIZE (16 * 1024)
  170. static char *local_send_buffer;
  171. typedef struct {
  172. WOLFSSL *ssl;
  173. request_st *r;
  174. connection *con;
  175. short renegotiations; /* count of SSL_CB_HANDSHAKE_START */
  176. short close_notify;
  177. unsigned short alpn;
  178. plugin_config conf;
  179. buffer *tmp_buf;
  180. log_error_st *errh;
  181. } handler_ctx;
  182. static handler_ctx *
  183. handler_ctx_init (void)
  184. {
  185. handler_ctx *hctx = calloc(1, sizeof(*hctx));
  186. force_assert(hctx);
  187. return hctx;
  188. }
  189. static void
  190. handler_ctx_free (handler_ctx *hctx)
  191. {
  192. if (hctx->ssl) SSL_free(hctx->ssl);
  193. free(hctx);
  194. }
  195. #ifdef HAVE_SESSION_TICKET
  196. /* ssl/ssl_local.h */
  197. #define TLSEXT_KEYNAME_LENGTH 16
  198. #define TLSEXT_TICK_KEY_LENGTH 32
  199. /* openssl has a huge number of interfaces, but not the most useful;
  200. * construct our own session ticket encryption key structure */
  201. typedef struct tlsext_ticket_key_st {
  202. time_t active_ts; /* tickets not issued w/ key until activation timestamp */
  203. time_t expire_ts; /* key not valid after expiration timestamp */
  204. unsigned char tick_key_name[TLSEXT_KEYNAME_LENGTH];
  205. unsigned char tick_hmac_key[TLSEXT_TICK_KEY_LENGTH];
  206. unsigned char tick_aes_key[TLSEXT_TICK_KEY_LENGTH];
  207. } tlsext_ticket_key_t;
  208. static tlsext_ticket_key_t session_ticket_keys[4];
  209. static time_t stek_rotate_ts;
  210. static int
  211. mod_openssl_session_ticket_key_generate (time_t active_ts, time_t expire_ts)
  212. {
  213. /* openssl RAND_*bytes() functions are called multiple times since the
  214. * funcs might have a 32-byte limit on number of bytes returned each call
  215. *
  216. * (Note: session ticket encryption key generation is not expected to fail)
  217. *
  218. * 3 keys are stored in session_ticket_keys[]
  219. * The 4th element of session_ticket_keys[] is used for STEK construction
  220. */
  221. /*(RAND_priv_bytes() not in openssl 1.1.0; introduced in openssl 1.1.1)*/
  222. #define RAND_priv_bytes(x,sz) RAND_bytes((x),(sz))
  223. if (RAND_bytes(session_ticket_keys[3].tick_key_name,
  224. TLSEXT_KEYNAME_LENGTH) <= 0
  225. || RAND_priv_bytes(session_ticket_keys[3].tick_hmac_key,
  226. TLSEXT_TICK_KEY_LENGTH) <= 0
  227. || RAND_priv_bytes(session_ticket_keys[3].tick_aes_key,
  228. TLSEXT_TICK_KEY_LENGTH) <= 0)
  229. return 0;
  230. session_ticket_keys[3].active_ts = active_ts;
  231. session_ticket_keys[3].expire_ts = expire_ts;
  232. return 1;
  233. }
  234. static void
  235. mod_openssl_session_ticket_key_rotate (void)
  236. {
  237. /* discard oldest key (session_ticket_keys[2]) and put newest key first
  238. * 3 keys are stored in session_ticket_keys[0], [1], [2]
  239. * session_ticket_keys[3] is used to construct and pass new STEK */
  240. session_ticket_keys[2] = session_ticket_keys[1];
  241. session_ticket_keys[1] = session_ticket_keys[0];
  242. /*memmove(session_ticket_keys+1,
  243. session_ticket_keys+0, sizeof(tlsext_ticket_key_t)*2);*/
  244. session_ticket_keys[0] = session_ticket_keys[3];
  245. wolfSSL_OPENSSL_cleanse(session_ticket_keys+3, sizeof(tlsext_ticket_key_t));
  246. }
  247. static tlsext_ticket_key_t *
  248. tlsext_ticket_key_get (void)
  249. {
  250. const time_t cur_ts = log_epoch_secs;
  251. const int e = sizeof(session_ticket_keys)/sizeof(*session_ticket_keys) - 1;
  252. for (int i = 0; i < e; ++i) {
  253. if (session_ticket_keys[i].active_ts > cur_ts) continue;
  254. if (session_ticket_keys[i].expire_ts < cur_ts) continue;
  255. return &session_ticket_keys[i];
  256. }
  257. return NULL;
  258. }
  259. static tlsext_ticket_key_t *
  260. tlsext_ticket_key_find (unsigned char key_name[16], int *refresh)
  261. {
  262. *refresh = 0;
  263. const time_t cur_ts = log_epoch_secs;
  264. const int e = sizeof(session_ticket_keys)/sizeof(*session_ticket_keys) - 1;
  265. for (int i = 0; i < e; ++i) {
  266. if (session_ticket_keys[i].expire_ts < cur_ts) continue;
  267. if (0 == memcmp(session_ticket_keys[i].tick_key_name, key_name, 16))
  268. return &session_ticket_keys[i];
  269. if (session_ticket_keys[i].active_ts <= cur_ts)
  270. *refresh = 1; /* newer active key is available */
  271. }
  272. return NULL;
  273. }
  274. static void
  275. tlsext_ticket_wipe_expired (const time_t cur_ts)
  276. {
  277. const int e = sizeof(session_ticket_keys)/sizeof(*session_ticket_keys) - 1;
  278. for (int i = 0; i < e; ++i) {
  279. if (session_ticket_keys[i].expire_ts != 0
  280. && session_ticket_keys[i].expire_ts < cur_ts)
  281. wolfSSL_OPENSSL_cleanse(session_ticket_keys+i,
  282. sizeof(tlsext_ticket_key_t));
  283. }
  284. }
  285. /* based on reference implementation from openssl 1.1.1g man page
  286. * man SSL_CTX_set_tlsext_ticket_key_cb
  287. * but openssl code uses EVP_aes_256_cbc() instead of EVP_aes_128_cbc()
  288. */
  289. #ifndef EVP_MAX_IV_LENGTH
  290. #define EVP_MAX_IV_LENGTH 16
  291. #endif
  292. static int
  293. ssl_tlsext_ticket_key_cb (SSL *s, unsigned char key_name[16],
  294. unsigned char iv[EVP_MAX_IV_LENGTH],
  295. EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)
  296. {
  297. UNUSED(s);
  298. if (enc) { /* create new session */
  299. tlsext_ticket_key_t *k = tlsext_ticket_key_get();
  300. if (NULL == k)
  301. return 0; /* current key does not exist or is not valid */
  302. memcpy(key_name, k->tick_key_name, 16);
  303. if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) <= 0)
  304. return -1; /* insufficient random */
  305. EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, k->tick_aes_key, iv);
  306. HMAC_Init_ex(hctx, k->tick_hmac_key, sizeof(k->tick_hmac_key),
  307. EVP_sha256(), NULL);
  308. return 1;
  309. }
  310. else { /* retrieve session */
  311. int refresh;
  312. tlsext_ticket_key_t *k = tlsext_ticket_key_find(key_name, &refresh);
  313. if (NULL == k)
  314. return 0;
  315. HMAC_Init_ex(hctx, k->tick_hmac_key, sizeof(k->tick_hmac_key),
  316. EVP_sha256(), NULL);
  317. EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, k->tick_aes_key, iv);
  318. return refresh ? 2 : 1;
  319. /* 'refresh' will trigger issuing new ticket for session
  320. * even though the current ticket is still valid */
  321. }
  322. }
  323. static int
  324. mod_openssl_session_ticket_key_file (const char *fn)
  325. {
  326. /* session ticket encryption key (STEK)
  327. *
  328. * STEK file should be stored in non-persistent storage,
  329. * e.g. /dev/shm/lighttpd/stek-file (in memory)
  330. * with appropriate permissions set to keep stek-file from being
  331. * read by other users. Where possible, systems should also be
  332. * configured without swap.
  333. *
  334. * admin should schedule an independent job to periodically
  335. * generate new STEK up to 3 times during key lifetime
  336. * (lighttpd stores up to 3 keys)
  337. *
  338. * format of binary file is:
  339. * 4-byte - format version (always 0; for use if format changes)
  340. * 4-byte - activation timestamp
  341. * 4-byte - expiration timestamp
  342. * 16-byte - session ticket key name
  343. * 32-byte - session ticket HMAC encrpytion key
  344. * 32-byte - session ticket AES encrpytion key
  345. *
  346. * STEK file can be created with a command such as:
  347. * dd if=/dev/random bs=1 count=80 status=none | \
  348. * perl -e 'print pack("iii",0,time()+300,time()+86400),<>' \
  349. * > STEK-file.$$ && mv STEK-file.$$ STEK-file
  350. *
  351. * The above delays activation time by 5 mins (+300 sec) to allow file to
  352. * be propagated to other machines. (admin must handle this independently)
  353. * If STEK generation is performed immediately prior to starting lighttpd,
  354. * admin should activate keys immediately (without +300).
  355. */
  356. int buf[23]; /* 92 bytes */
  357. int rc = 0; /*(will retry on next check interval upon any error)*/
  358. if (0 != fdevent_load_file_bytes((char *)buf,(off_t)sizeof(buf),0,fn,NULL))
  359. return rc;
  360. if (buf[0] == 0) { /*(format version 0)*/
  361. session_ticket_keys[3].active_ts = buf[1];
  362. session_ticket_keys[3].expire_ts = buf[2];
  363. #ifndef __COVERITY__ /* intentional; hide from Coverity Scan */
  364. /* intentionally copy 80 bytes into consecutive arrays
  365. * tick_key_name[], tick_hmac_key[], tick_aes_key[] */
  366. memcpy(&session_ticket_keys[3].tick_key_name, buf+3, 80);
  367. #endif
  368. rc = 1;
  369. }
  370. wolfSSL_OPENSSL_cleanse(buf, sizeof(buf));
  371. return rc;
  372. }
  373. static void
  374. mod_openssl_session_ticket_key_check (const plugin_data *p, const time_t cur_ts)
  375. {
  376. int rotate = 0;
  377. if (p->ssl_stek_file) {
  378. struct stat st;
  379. if (0 == stat(p->ssl_stek_file, &st) && st.st_mtime > stek_rotate_ts)
  380. rotate = mod_openssl_session_ticket_key_file(p->ssl_stek_file);
  381. tlsext_ticket_wipe_expired(cur_ts);
  382. }
  383. else if (cur_ts - 28800 >= stek_rotate_ts) /*(8 hours)*/
  384. rotate = mod_openssl_session_ticket_key_generate(cur_ts, cur_ts+86400);
  385. if (rotate) {
  386. mod_openssl_session_ticket_key_rotate();
  387. stek_rotate_ts = cur_ts;
  388. }
  389. }
  390. #endif /* HAVE_SESSION_TICKET */
  391. #ifdef HAVE_OCSP
  392. static int
  393. ssl_tlsext_status_cb(SSL *ssl, void *arg)
  394. {
  395. #ifdef SSL_get_tlsext_status_type
  396. if (TLSEXT_STATUSTYPE_ocsp != SSL_get_tlsext_status_type(ssl))
  397. return SSL_TLSEXT_ERR_NOACK; /* ignore if not client OCSP request */
  398. #endif
  399. handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
  400. buffer *ssl_stapling = hctx->conf.pc->ssl_stapling;
  401. if (NULL == ssl_stapling) return SSL_TLSEXT_ERR_NOACK;
  402. UNUSED(arg);
  403. int len = (int)buffer_string_length(ssl_stapling);
  404. /* WolfSSL does not require copy */
  405. uint8_t *ocsp_resp = (uint8_t *)ssl_stapling->ptr;
  406. if (!SSL_set_tlsext_status_ocsp_resp(ssl, ocsp_resp, len)) {
  407. log_error(hctx->r->conf.errh, __FILE__, __LINE__,
  408. "SSL: failed to set OCSP response for TLS server name %s: %s",
  409. hctx->r->uri.authority.ptr, ERR_error_string(ERR_get_error(), NULL));
  410. return SSL_TLSEXT_ERR_NOACK; /* ignore OCSP request if error occurs */
  411. /*return SSL_TLSEXT_ERR_ALERT_FATAL;*/
  412. }
  413. return SSL_TLSEXT_ERR_OK;
  414. }
  415. #endif
  416. INIT_FUNC(mod_openssl_init)
  417. {
  418. plugin_data_singleton = (plugin_data *)calloc(1, sizeof(plugin_data));
  419. #ifdef DEBUG_WOLFSSL
  420. wolfSSL_Debugging_ON();
  421. #endif
  422. return plugin_data_singleton;
  423. }
  424. static int mod_openssl_init_once_openssl (server *srv)
  425. {
  426. if (ssl_is_init) return 1;
  427. if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
  428. log_error(srv->errh, __FILE__, __LINE__,
  429. "SSL: wolfSSL_Init() failed");
  430. return 0;
  431. }
  432. ssl_is_init = 1;
  433. if (0 == RAND_status()) {
  434. log_error(srv->errh, __FILE__, __LINE__,
  435. "SSL: not enough entropy in the pool");
  436. return 0;
  437. }
  438. local_send_buffer = malloc(LOCAL_SEND_BUFSIZE);
  439. force_assert(NULL != local_send_buffer);
  440. return 1;
  441. }
  442. static void mod_openssl_free_openssl (void)
  443. {
  444. if (!ssl_is_init) return;
  445. #ifdef HAVE_SESSION_TICKET
  446. wolfSSL_OPENSSL_cleanse(session_ticket_keys, sizeof(session_ticket_keys));
  447. stek_rotate_ts = 0;
  448. #endif
  449. if (wolfSSL_Cleanup() != WOLFSSL_SUCCESS) {
  450. log_error(plugin_data_singleton->srv->errh, __FILE__, __LINE__,
  451. "SSL: wolfSSL_Cleanup() failed");
  452. }
  453. free(local_send_buffer);
  454. ssl_is_init = 0;
  455. }
  456. static void
  457. mod_wolfssl_free_der_certs (buffer **certs)
  458. {
  459. if (NULL == certs) return;
  460. for (int i = 0; NULL != certs[i]; ++i)
  461. buffer_free(certs[i]);
  462. free(certs);
  463. }
  464. static void
  465. mod_openssl_free_config (server *srv, plugin_data * const p)
  466. {
  467. array_free(p->cafiles);
  468. if (NULL != p->ssl_ctxs) {
  469. SSL_CTX * const ssl_ctx_global_scope = p->ssl_ctxs->ssl_ctx;
  470. /* free ssl_ctx from $SERVER["socket"] (if not copy of global scope) */
  471. for (uint32_t i = 1; i < srv->config_context->used; ++i) {
  472. plugin_ssl_ctx * const s = p->ssl_ctxs + i;
  473. if (s->ssl_ctx && s->ssl_ctx != ssl_ctx_global_scope)
  474. SSL_CTX_free(s->ssl_ctx);
  475. }
  476. /* free ssl_ctx from global scope */
  477. if (ssl_ctx_global_scope)
  478. SSL_CTX_free(ssl_ctx_global_scope);
  479. free(p->ssl_ctxs);
  480. }
  481. if (NULL == p->cvlist) return;
  482. /* (init i to 0 if global context; to 1 to skip empty global context) */
  483. for (int i = !p->cvlist[0].v.u2[1], used = p->nconfig; i < used; ++i) {
  484. config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
  485. for (; -1 != cpv->k_id; ++cpv) {
  486. switch (cpv->k_id) {
  487. case 0: /* ssl.pemfile */
  488. if (cpv->vtype == T_CONFIG_LOCAL) {
  489. plugin_cert *pc = cpv->v.v;
  490. buffer_free(pc->ssl_pemfile_pkey);
  491. /*buffer_free(pc->ssl_pemfile_x509);*//*(part of chain)*/
  492. mod_wolfssl_free_der_certs(pc->ssl_pemfile_chain);
  493. buffer_free(pc->ssl_stapling);
  494. free(pc);
  495. }
  496. break;
  497. case 2: /* ssl.ca-file */
  498. if (cpv->vtype == T_CONFIG_LOCAL) {
  499. plugin_cacerts *cacerts = cpv->v.v;
  500. wolfSSL_sk_X509_NAME_pop_free(cacerts->names,
  501. X509_NAME_free);
  502. wolfSSL_X509_STORE_free(cacerts->certs);
  503. free(cacerts);
  504. }
  505. break;
  506. case 3: /* ssl.ca-dn-file */
  507. if (cpv->vtype == T_CONFIG_LOCAL)
  508. wolfSSL_sk_X509_NAME_pop_free(cpv->v.v, X509_NAME_free);
  509. break;
  510. default:
  511. break;
  512. }
  513. }
  514. }
  515. }
  516. /* WolfSSL OpenSSL compat API does not wipe temp mem used; write our own */
  517. /* (pemfile might contain private key)*/
  518. /* code here is based on similar code in mod_nss */
  519. #include "base64.h"
  520. #define PEM_BEGIN "-----BEGIN "
  521. #define PEM_END "-----END "
  522. #define PEM_BEGIN_CERT "-----BEGIN CERTIFICATE-----"
  523. #define PEM_END_CERT "-----END CERTIFICATE-----"
  524. #define PEM_BEGIN_TRUSTED_CERT "-----BEGIN TRUSTED CERTIFICATE-----"
  525. #define PEM_END_TRUSTED_CERT "-----END TRUSTED CERTIFICATE-----"
  526. #define PEM_BEGIN_PKEY "-----BEGIN PRIVATE KEY-----"
  527. #define PEM_END_PKEY "-----END PRIVATE KEY-----"
  528. #define PEM_BEGIN_EC_PKEY "-----BEGIN EC PRIVATE KEY-----"
  529. #define PEM_END_EC_PKEY "-----END EC PRIVATE KEY-----"
  530. #define PEM_BEGIN_RSA_PKEY "-----BEGIN RSA PRIVATE KEY-----"
  531. #define PEM_END_RSA_PKEY "-----END RSA PRIVATE KEY-----"
  532. #define PEM_BEGIN_DSA_PKEY "-----BEGIN DSA PRIVATE KEY-----"
  533. #define PEM_END_DSA_PKEY "-----END DSA PRIVATE KEY-----"
  534. #define PEM_BEGIN_ANY_PKEY "-----BEGIN ANY PRIVATE KEY-----"
  535. #define PEM_END_ANY_PKEY "-----END ANY PRIVATE KEY-----"
  536. /* (not implemented: support to get password from user for encrypted key) */
  537. #define PEM_BEGIN_ENCRYPTED_PKEY "-----BEGIN ENCRYPTED PRIVATE KEY-----"
  538. #define PEM_END_ENCRYPTED_PKEY "-----END ENCRYPTED PRIVATE KEY-----"
  539. #define PEM_BEGIN_X509_CRL "-----BEGIN X509 CRL-----"
  540. #define PEM_END_X509_CRL "-----END X509 CRL-----"
  541. static buffer *
  542. mod_wolfssl_load_pem_file (const char *fn, log_error_st *errh, buffer ***chain)
  543. {
  544. off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
  545. char *data = fdevent_load_file(fn, &dlen, errh, malloc, free);
  546. if (NULL == data) return NULL;
  547. buffer **certs = NULL;
  548. int rc = -1;
  549. do {
  550. int count = 0;
  551. char *b = data;
  552. for (; (b = strstr(b, PEM_BEGIN_CERT)); b += sizeof(PEM_BEGIN_CERT)-1)
  553. ++count;
  554. b = data;
  555. for (; (b = strstr(b, PEM_BEGIN_TRUSTED_CERT));
  556. b += sizeof(PEM_BEGIN_TRUSTED_CERT)-1)
  557. ++count;
  558. if (0 == count) {
  559. rc = 0;
  560. break;
  561. }
  562. certs = malloc((count+1) * sizeof(buffer *));
  563. force_assert(NULL != certs);
  564. certs[count] = NULL;
  565. for (int i = 0; i < count; ++i)
  566. certs[i] = buffer_init();
  567. buffer *der;
  568. int i = 0;
  569. for (char *e = data; (b = strstr(e, PEM_BEGIN_CERT)); ++i) {
  570. b += sizeof(PEM_BEGIN_CERT)-1;
  571. if (*b == '\r') ++b;
  572. if (*b == '\n') ++b;
  573. e = strstr(b, PEM_END_CERT);
  574. if (NULL == e) break;
  575. uint32_t len = (uint32_t)(e - b);
  576. e += sizeof(PEM_END_CERT)-1;
  577. if (i >= count) break; /*(should not happen)*/
  578. der = certs[i];
  579. if (NULL == buffer_append_base64_decode(der,b,len,BASE64_STANDARD))
  580. break;
  581. }
  582. for (char *e = data; (b = strstr(e, PEM_BEGIN_TRUSTED_CERT)); ++i) {
  583. b += sizeof(PEM_BEGIN_TRUSTED_CERT)-1;
  584. if (*b == '\r') ++b;
  585. if (*b == '\n') ++b;
  586. e = strstr(b, PEM_END_TRUSTED_CERT);
  587. if (NULL == e) break;
  588. uint32_t len = (uint32_t)(e - b);
  589. e += sizeof(PEM_END_TRUSTED_CERT)-1;
  590. if (i >= count) break; /*(should not happen)*/
  591. der = certs[i];
  592. if (NULL == buffer_append_base64_decode(der,b,len,BASE64_STANDARD))
  593. break;
  594. }
  595. if (i == count)
  596. rc = 0;
  597. else
  598. errno = EIO;
  599. } while (0);
  600. if (dlen) safe_memclear(data, dlen);
  601. free(data);
  602. if (rc < 0) {
  603. log_perror(errh, __FILE__, __LINE__, "error loading %s", fn);
  604. mod_wolfssl_free_der_certs(certs);
  605. certs = NULL;
  606. }
  607. *chain = certs;
  608. return certs ? certs[0] : NULL;
  609. }
  610. static buffer *
  611. mod_wolfssl_evp_pkey_load_pem_file (const char *fn, log_error_st *errh)
  612. {
  613. off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
  614. char *data = fdevent_load_file(fn, &dlen, errh, malloc, free);
  615. if (NULL == data) return NULL;
  616. buffer *pkey = NULL;
  617. int rc = -1;
  618. do {
  619. /*(expecting single private key in file, so first match)*/
  620. char *b, *e;
  621. if ((b = strstr(data, PEM_BEGIN_PKEY))
  622. && (e = strstr(b, PEM_END_PKEY)))
  623. b += sizeof(PEM_BEGIN_PKEY)-1;
  624. else if ((b = strstr(data, PEM_BEGIN_EC_PKEY))
  625. && (e = strstr(b, PEM_END_EC_PKEY)))
  626. b += sizeof(PEM_BEGIN_EC_PKEY)-1;
  627. else if ((b = strstr(data, PEM_BEGIN_RSA_PKEY))
  628. && (e = strstr(b, PEM_END_RSA_PKEY)))
  629. b += sizeof(PEM_BEGIN_RSA_PKEY)-1;
  630. else if ((b = strstr(data, PEM_BEGIN_DSA_PKEY))
  631. && (e = strstr(b, PEM_END_DSA_PKEY)))
  632. b += sizeof(PEM_BEGIN_DSA_PKEY)-1;
  633. else if ((b = strstr(data, PEM_BEGIN_ANY_PKEY))
  634. && (e = strstr(b, PEM_END_ANY_PKEY)))
  635. b += sizeof(PEM_BEGIN_ANY_PKEY)-1;
  636. else
  637. break;
  638. if (*b == '\r') ++b;
  639. if (*b == '\n') ++b;
  640. pkey = buffer_init();
  641. size_t len = (size_t)(e - b);
  642. if (NULL == buffer_append_base64_decode(pkey, b, len, BASE64_STANDARD))
  643. break;
  644. rc = 0;
  645. } while (0);
  646. if (dlen) safe_memclear(data, dlen);
  647. free(data);
  648. if (rc < 0) {
  649. log_error(errh, __FILE__, __LINE__, "%s() %s", __func__, fn);
  650. return NULL;
  651. }
  652. return pkey;
  653. }
  654. static int
  655. mod_wolfssl_CTX_use_certificate_chain_file (WOLFSSL_CTX *ssl_ctx, const char *fn, log_error_st *errh)
  656. {
  657. /* (While it should be possible to parse DERs from (buffer **)
  658. * s->pc->ssl_pemfile_chain, it is simpler to re-read file and use the
  659. * built-in wolfSSL_CTX_use_certificate_chain_buffer() interface) */
  660. off_t dlen = 4*1024*1024;/*(arbitrary limit: 4 MB file; expect < 1 KB)*/
  661. char *data = fdevent_load_file(fn, &dlen, errh, malloc, free);
  662. if (NULL == data) return -1;
  663. int rc = wolfSSL_CTX_use_certificate_chain_buffer(ssl_ctx,
  664. (unsigned char *)data,
  665. (long)dlen);
  666. if (dlen) safe_memclear(data, dlen);
  667. free(data);
  668. if (rc == WOLFSSL_SUCCESS)
  669. return 1;
  670. log_error(errh, __FILE__, __LINE__,
  671. "SSL: %s %s", ERR_error_string(rc, NULL), fn);
  672. return 0;
  673. }
  674. static STACK_OF(X509_NAME) *
  675. mod_wolfssl_load_client_CA_file (const buffer *ssl_ca_file, log_error_st *errh)
  676. {
  677. /* similar to wolfSSL_load_client_CA_file(), plus some processing */
  678. buffer **certs = NULL;
  679. if (NULL == mod_wolfssl_load_pem_file(ssl_ca_file->ptr, errh, &certs)) {
  680. #ifdef __clang_analyzer__
  681. mod_wolfssl_free_der_certs(certs); /*unnecessary; quiet clang analyzer*/
  682. #endif
  683. return NULL;
  684. }
  685. WOLF_STACK_OF(WOLFSSL_X509_NAME) *canames = wolfSSL_sk_X509_NAME_new(NULL);
  686. if (NULL == canames) {
  687. mod_wolfssl_free_der_certs(certs);
  688. return NULL;
  689. }
  690. for (int i = 0; NULL != certs[i]; ++i) {
  691. WOLFSSL_X509 *ca =
  692. wolfSSL_X509_load_certificate_buffer((unsigned char *)certs[i]->ptr,
  693. (int)
  694. buffer_string_length(certs[i]),
  695. WOLFSSL_FILETYPE_ASN1);
  696. WOLFSSL_X509_NAME *subj = NULL;
  697. if (NULL == ca
  698. || NULL == (subj = wolfSSL_X509_get_subject_name(ca))
  699. || 0 != wolfSSL_sk_X509_NAME_push(canames,
  700. wolfSSL_X509_NAME_dup(subj))) {
  701. log_error(errh, __FILE__, __LINE__,
  702. "SSL: couldn't read X509 certificates from '%s'",
  703. ssl_ca_file->ptr);
  704. if (subj) wolfSSL_X509_NAME_free(subj);
  705. if (ca) wolfSSL_X509_free(ca);
  706. wolfSSL_sk_X509_NAME_free(canames);
  707. mod_wolfssl_free_der_certs(certs);
  708. return NULL;
  709. }
  710. wolfSSL_X509_free(ca);
  711. }
  712. mod_wolfssl_free_der_certs(certs);
  713. return canames;
  714. }
  715. static plugin_cacerts *
  716. mod_wolfssl_load_cacerts (const buffer *ssl_ca_file, log_error_st *errh)
  717. {
  718. /* similar to mod_wolfSSL_load_client_CA_file(), plus some processing */
  719. /* similar to wolfSSL_load_client_CA_file(), plus some processing */
  720. buffer **certs = NULL;
  721. if (NULL == mod_wolfssl_load_pem_file(ssl_ca_file->ptr, errh, &certs)) {
  722. #ifdef __clang_analyzer__
  723. mod_wolfssl_free_der_certs(certs); /*unnecessary; quiet clang analyzer*/
  724. #endif
  725. return NULL;
  726. }
  727. WOLFSSL_X509_STORE *castore = wolfSSL_X509_STORE_new();
  728. if (NULL == castore) {
  729. mod_wolfssl_free_der_certs(certs);
  730. return NULL;
  731. }
  732. WOLF_STACK_OF(WOLFSSL_X509_NAME) *canames = wolfSSL_sk_X509_NAME_new(NULL);
  733. if (NULL == canames) {
  734. wolfSSL_X509_STORE_free(castore);
  735. mod_wolfssl_free_der_certs(certs);
  736. return NULL;
  737. }
  738. for (int i = 0; NULL != certs[i]; ++i) {
  739. WOLFSSL_X509 *ca =
  740. wolfSSL_X509_load_certificate_buffer((unsigned char *)certs[i]->ptr,
  741. (int)
  742. buffer_string_length(certs[i]),
  743. WOLFSSL_FILETYPE_ASN1);
  744. WOLFSSL_X509_NAME *subj = NULL;
  745. if (NULL == ca || !wolfSSL_X509_STORE_add_cert(castore, ca)
  746. || NULL == (subj = wolfSSL_X509_get_subject_name(ca))
  747. || 0 != wolfSSL_sk_X509_NAME_push(canames,
  748. wolfSSL_X509_NAME_dup(subj))) {
  749. log_error(errh, __FILE__, __LINE__,
  750. "SSL: couldn't read X509 certificates from '%s'",
  751. ssl_ca_file->ptr);
  752. if (subj) wolfSSL_X509_NAME_free(subj);
  753. if (ca) wolfSSL_X509_free(ca);
  754. wolfSSL_sk_X509_NAME_free(canames);
  755. wolfSSL_X509_STORE_free(castore);
  756. mod_wolfssl_free_der_certs(certs);
  757. return NULL;
  758. }
  759. wolfSSL_X509_free(ca);
  760. }
  761. mod_wolfssl_free_der_certs(certs);
  762. plugin_cacerts *cacerts = malloc(sizeof(plugin_cacerts));
  763. force_assert(cacerts);
  764. cacerts->names = canames;
  765. cacerts->certs = castore;
  766. return cacerts;
  767. }
  768. static int
  769. mod_wolfssl_load_cacrls (WOLFSSL_CTX *ssl_ctx, const buffer *ssl_ca_crl_file, server *srv)
  770. {
  771. #ifdef HAVE_CRL /* <wolfssl/options.h> */
  772. int rc = wolfSSL_CTX_EnableCRL(ssl_ctx,
  773. WOLFSSL_CRL_CHECK | WOLFSSL_CRL_CHECKALL);
  774. if (rc != WOLFSSL_SUCCESS) return 0;
  775. const char *fn = ssl_ca_crl_file->ptr;
  776. off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
  777. char *data = fdevent_load_file(fn, &dlen, srv->errh, malloc, free);
  778. if (NULL == data) return 0;
  779. rc = wolfSSL_CTX_LoadCRLBuffer(ssl_ctx, (byte *)data, (long)dlen,
  780. WOLFSSL_FILETYPE_PEM);
  781. if (dlen) safe_memclear(data, dlen);
  782. free(data);
  783. if (rc == WOLFSSL_SUCCESS)
  784. return 1;
  785. log_error(srv->errh, __FILE__, __LINE__,
  786. "SSL: %s %s", ERR_error_string(rc, NULL), fn);
  787. return 0;
  788. #else
  789. UNUSED(ssl_ctx);
  790. log_error(srv->errh, __FILE__, __LINE__,
  791. "WolfSSL not built with CRL support; ignoring %s", ssl_ca_crl_file->ptr);
  792. return WOLFSSL_FAILURE;
  793. #endif
  794. }
  795. static int
  796. mod_wolfssl_load_verify_locn (SSL_CTX *ssl_ctx, const buffer *b, server *srv)
  797. {
  798. const char *fn = b->ptr;
  799. off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
  800. char *data = fdevent_load_file(fn, &dlen, srv->errh, malloc, free);
  801. if (NULL == data) return 0;
  802. int rc = wolfSSL_CTX_load_verify_buffer(ssl_ctx, (unsigned char *)data,
  803. (long)dlen, WOLFSSL_FILETYPE_PEM);
  804. if (dlen) safe_memclear(data, dlen);
  805. free(data);
  806. if (rc == WOLFSSL_SUCCESS)
  807. return 1;
  808. log_error(srv->errh, __FILE__, __LINE__,
  809. "SSL: %s %s", ERR_error_string(rc, NULL), fn);
  810. return 0;
  811. }
  812. static int
  813. mod_wolfssl_load_ca_files (SSL_CTX *ssl_ctx, plugin_data *p, server *srv)
  814. {
  815. /* load all ssl.ca-files specified in the config into each SSL_CTX */
  816. for (uint32_t i = 0, used = p->cafiles->used; i < used; ++i) {
  817. const buffer *b = &((data_string *)p->cafiles->data[i])->value;
  818. if (!mod_wolfssl_load_verify_locn(ssl_ctx, b, srv))
  819. return 0;
  820. }
  821. return 1;
  822. }
  823. FREE_FUNC(mod_openssl_free)
  824. {
  825. plugin_data *p = p_d;
  826. if (NULL == p->srv) return;
  827. mod_openssl_free_config(p->srv, p);
  828. mod_openssl_free_openssl();
  829. }
  830. static void
  831. mod_openssl_merge_config_cpv (plugin_config * const pconf, const config_plugin_value_t * const cpv)
  832. {
  833. switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */
  834. case 0: /* ssl.pemfile */
  835. if (cpv->vtype == T_CONFIG_LOCAL)
  836. pconf->pc = cpv->v.v;
  837. break;
  838. case 1: /* ssl.privkey */
  839. break;
  840. case 2: /* ssl.ca-file */
  841. if (cpv->vtype == T_CONFIG_LOCAL)
  842. pconf->ssl_ca_file = cpv->v.v;
  843. break;
  844. case 3: /* ssl.ca-dn-file */
  845. if (cpv->vtype == T_CONFIG_LOCAL)
  846. pconf->ssl_ca_dn_file = cpv->v.v;
  847. break;
  848. case 4: /* ssl.ca-crl-file */
  849. pconf->ssl_ca_crl_file = cpv->v.b;
  850. break;
  851. case 5: /* ssl.read-ahead */
  852. pconf->ssl_read_ahead = (0 != cpv->v.u);
  853. break;
  854. case 6: /* ssl.disable-client-renegotiation */
  855. pconf->ssl_disable_client_renegotiation = (0 != cpv->v.u);
  856. break;
  857. case 7: /* ssl.verifyclient.activate */
  858. pconf->ssl_verifyclient = (0 != cpv->v.u);
  859. break;
  860. case 8: /* ssl.verifyclient.enforce */
  861. pconf->ssl_verifyclient_enforce = (0 != cpv->v.u);
  862. break;
  863. case 9: /* ssl.verifyclient.depth */
  864. pconf->ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
  865. break;
  866. case 10:/* ssl.verifyclient.username */
  867. pconf->ssl_verifyclient_username = cpv->v.b;
  868. break;
  869. case 11:/* ssl.verifyclient.exportcert */
  870. pconf->ssl_verifyclient_export_cert = (0 != cpv->v.u);
  871. break;
  872. case 12:/* ssl.acme-tls-1 */
  873. pconf->ssl_acme_tls_1 = cpv->v.b;
  874. break;
  875. case 13:/* ssl.stapling-file */
  876. break;
  877. case 14:/* debug.log-ssl-noise */
  878. pconf->ssl_log_noise = (0 != cpv->v.u);
  879. break;
  880. default:/* should not happen */
  881. return;
  882. }
  883. }
  884. static void
  885. mod_openssl_merge_config(plugin_config * const pconf, const config_plugin_value_t *cpv)
  886. {
  887. do {
  888. mod_openssl_merge_config_cpv(pconf, cpv);
  889. } while ((++cpv)->k_id != -1);
  890. }
  891. static void
  892. mod_openssl_patch_config (request_st * const r, plugin_config * const pconf)
  893. {
  894. plugin_data * const p = plugin_data_singleton;
  895. memcpy(pconf, &p->defaults, sizeof(plugin_config));
  896. for (int i = 1, used = p->nconfig; i < used; ++i) {
  897. if (config_check_cond(r, (uint32_t)p->cvlist[i].k_id))
  898. mod_openssl_merge_config(pconf, p->cvlist + p->cvlist[i].v.u2[0]);
  899. }
  900. }
  901. static int
  902. safer_X509_NAME_oneline(X509_NAME *name, char *buf, size_t sz)
  903. {
  904. #if LIBWOLFSSL_VERSION_HEX < 0x04003000
  905. UNUSED(name);
  906. UNUSED(sz);
  907. #else
  908. if (wolfSSL_X509_get_name_oneline(name, buf, (int)sz))
  909. return (int)strlen(buf);
  910. else
  911. #endif
  912. {
  913. buf[0] = '\0';
  914. return -1;
  915. }
  916. }
  917. static void
  918. ssl_info_callback (const SSL *ssl, int where, int ret)
  919. {
  920. UNUSED(ret);
  921. if (0 != (where & SSL_CB_HANDSHAKE_START)) {
  922. handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
  923. if (hctx->renegotiations >= 0) ++hctx->renegotiations;
  924. }
  925. /* https://github.com/openssl/openssl/issues/5721
  926. * "TLSv1.3 unexpected InfoCallback after handshake completed" */
  927. if (0 != (where & SSL_CB_HANDSHAKE_DONE)) {
  928. /* SSL_version() is valid after initial handshake completed */
  929. SSL *ssl_nonconst;
  930. *(const SSL **)&ssl_nonconst = ssl;
  931. if (wolfSSL_GetVersion(ssl_nonconst) >= WOLFSSL_TLSV1_3) {
  932. /* https://wiki.openssl.org/index.php/TLS1.3
  933. * "Renegotiation is not possible in a TLSv1.3 connection" */
  934. handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
  935. hctx->renegotiations = -1;
  936. }
  937. }
  938. }
  939. /* https://wiki.openssl.org/index.php/Manual:SSL_CTX_set_verify(3)#EXAMPLES */
  940. static int
  941. verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
  942. {
  943. char buf[256];
  944. X509 *err_cert;
  945. int err, depth;
  946. SSL *ssl;
  947. handler_ctx *hctx;
  948. err = X509_STORE_CTX_get_error(ctx);
  949. depth = X509_STORE_CTX_get_error_depth(ctx);
  950. /*
  951. * Retrieve the pointer to the SSL of the connection currently treated
  952. * and the application specific data stored into the SSL object.
  953. */
  954. ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
  955. hctx = (handler_ctx *) SSL_get_app_data(ssl);
  956. /*
  957. * Catch a too long certificate chain. The depth limit set using
  958. * wolfSSL_CTX_set_verify_depth() is by purpose set to "limit+1" so
  959. * that whenever the "depth>verify_depth" condition is met, we
  960. * have violated the limit and want to log this error condition.
  961. * We must do it here, because the CHAIN_TOO_LONG error would not
  962. * be found explicitly; only errors introduced by cutting off the
  963. * additional certificates would be logged.
  964. */
  965. if (depth > hctx->conf.ssl_verifyclient_depth) {
  966. preverify_ok = 0;
  967. err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
  968. X509_STORE_CTX_set_error(ctx, err);
  969. }
  970. if (preverify_ok && 0 == depth && NULL != hctx->conf.ssl_ca_dn_file) {
  971. /* verify that client cert is issued by CA in ssl.ca-dn-file
  972. * if both ssl.ca-dn-file and ssl.ca-file were configured */
  973. STACK_OF(X509_NAME) * const cert_names = hctx->conf.ssl_ca_dn_file;
  974. X509_NAME *issuer;
  975. err_cert = ctx->current_cert;/*wolfSSL_X509_STORE_CTX_get_current_cert*/
  976. if (NULL == err_cert) return !hctx->conf.ssl_verifyclient_enforce;
  977. issuer = X509_get_issuer_name(err_cert);
  978. #if 0 /*(?desirable/undesirable to have cert_names sorted?)*/
  979. if (-1 != sk_X509_NAME_find(cert_names, issuer))
  980. return preverify_ok; /* match */
  981. #else
  982. for (int i=0, len=wolfSSL_sk_X509_NAME_num(cert_names); i < len; ++i) {
  983. if (0 == wolfSSL_X509_NAME_cmp(sk_X509_NAME_value(cert_names, i),
  984. issuer))
  985. return preverify_ok; /* match */
  986. }
  987. #endif
  988. preverify_ok = 0;
  989. err = X509_V_ERR_CERT_REJECTED;
  990. X509_STORE_CTX_set_error(ctx, err);
  991. }
  992. if (preverify_ok) {
  993. return preverify_ok;
  994. }
  995. err_cert = ctx->current_cert; /*wolfSSL_X509_STORE_CTX_get_current_cert()*/
  996. if (NULL == err_cert) return !hctx->conf.ssl_verifyclient_enforce;
  997. safer_X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf));
  998. log_error_st *errh = hctx->r->conf.errh;
  999. log_error(errh, __FILE__, __LINE__,
  1000. "SSL: verify error:num=%d:%s:depth=%d:subject=%s",
  1001. err, X509_verify_cert_error_string(err), depth, buf);
  1002. /*
  1003. * At this point, err contains the last verification error. We can use
  1004. * it for something special
  1005. */
  1006. if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
  1007. err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) {
  1008. safer_X509_NAME_oneline(X509_get_issuer_name(err_cert),buf,sizeof(buf));
  1009. log_error(errh, __FILE__, __LINE__, "SSL: issuer=%s", buf);
  1010. }
  1011. return !hctx->conf.ssl_verifyclient_enforce;
  1012. }
  1013. static int
  1014. mod_openssl_cert_cb (SSL *ssl, void *arg)
  1015. {
  1016. handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
  1017. plugin_cert *pc = hctx->conf.pc;
  1018. UNUSED(arg);
  1019. if (NULL == pc->ssl_pemfile_x509 || NULL == pc->ssl_pemfile_pkey) {
  1020. /* x509/pkey available <=> pemfile was set <=> pemfile got patched:
  1021. * so this should never happen, unless you nest $SERVER["socket"] */
  1022. log_error(hctx->r->conf.errh, __FILE__, __LINE__,
  1023. "SSL: no certificate/private key for TLS server name %s",
  1024. hctx->r->uri.authority.ptr);
  1025. return 0;
  1026. }
  1027. /* first set certificate!
  1028. * setting private key checks whether certificate matches it */
  1029. buffer *cert = pc->ssl_pemfile_x509;
  1030. if (1 != wolfSSL_use_certificate_ASN1(ssl, (unsigned char *)cert->ptr,
  1031. (int)buffer_string_length(cert))) {
  1032. log_error(hctx->r->conf.errh, __FILE__, __LINE__,
  1033. "SSL: failed to set certificate for TLS server name %s: %s",
  1034. hctx->r->uri.authority.ptr, ERR_error_string(ERR_get_error(), NULL));
  1035. return 0;
  1036. }
  1037. buffer *pkey = pc->ssl_pemfile_pkey;
  1038. if (1 != wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char *)pkey->ptr,
  1039. (int)buffer_string_length(pkey),
  1040. WOLFSSL_FILETYPE_ASN1)) {
  1041. log_error(hctx->r->conf.errh, __FILE__, __LINE__,
  1042. "SSL: failed to set private key for TLS server name %s: %s",
  1043. hctx->r->uri.authority.ptr, ERR_error_string(ERR_get_error(), NULL));
  1044. return 0;
  1045. }
  1046. if (hctx->conf.ssl_verifyclient) {
  1047. if (NULL == hctx->conf.ssl_ca_file) {
  1048. log_error(hctx->r->conf.errh, __FILE__, __LINE__,
  1049. "SSL: can't verify client without ssl.ca-file "
  1050. "for TLS server name %s", hctx->r->uri.authority.ptr);
  1051. return 0;
  1052. }
  1053. /* WolfSSL does not support setting per-session CA list;
  1054. * limitation is to per-CTX CA list, and is not changed after SNI */
  1055. int mode = SSL_VERIFY_PEER;
  1056. if (hctx->conf.ssl_verifyclient_enforce)
  1057. mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
  1058. wolfSSL_set_verify(ssl, mode, verify_callback);
  1059. wolfSSL_set_verify_depth(ssl, hctx->conf.ssl_verifyclient_depth + 1);
  1060. }
  1061. else {
  1062. wolfSSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
  1063. }
  1064. return 1;
  1065. }
  1066. #ifdef HAVE_TLS_EXTENSIONS
  1067. static int
  1068. mod_openssl_SNI (handler_ctx *hctx, const char *servername, size_t len)
  1069. {
  1070. request_st * const r = hctx->r;
  1071. if (len >= 1024) { /*(expecting < 256; TLSEXT_MAXLEN_host_name is 255)*/
  1072. log_error(r->conf.errh, __FILE__, __LINE__,
  1073. "SSL: SNI name too long %.*s", (int)len, servername);
  1074. return SSL_TLSEXT_ERR_ALERT_FATAL;
  1075. }
  1076. /* use SNI to patch mod_openssl config and then reset COMP_HTTP_HOST */
  1077. buffer_copy_string_len(&r->uri.authority, servername, len);
  1078. buffer_to_lower(&r->uri.authority);
  1079. #if 0
  1080. /*(r->uri.authority used below for configuration before request read;
  1081. * revisit for h2)*/
  1082. if (0 != http_request_host_policy(&r->uri.authority,
  1083. r->conf.http_parseopts, 443))
  1084. return SSL_TLSEXT_ERR_ALERT_FATAL;
  1085. #endif
  1086. r->conditional_is_valid |= (1 << COMP_HTTP_SCHEME)
  1087. | (1 << COMP_HTTP_HOST);
  1088. mod_openssl_patch_config(r, &hctx->conf);
  1089. /* reset COMP_HTTP_HOST so that conditions re-run after request hdrs read */
  1090. /*(done in response.c:config_cond_cache_reset() after request hdrs read)*/
  1091. /*config_cond_cache_reset_item(r, COMP_HTTP_HOST);*/
  1092. /*buffer_clear(&r->uri.authority);*/
  1093. return (mod_openssl_cert_cb(hctx->ssl, NULL) == 1)
  1094. ? SSL_TLSEXT_ERR_OK
  1095. : SSL_TLSEXT_ERR_ALERT_FATAL;
  1096. }
  1097. static int
  1098. network_ssl_servername_callback (SSL *ssl, int *al, void *srv)
  1099. {
  1100. handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
  1101. buffer_copy_string(&hctx->r->uri.scheme, "https");
  1102. UNUSED(al);
  1103. UNUSED(srv);
  1104. const char *servername;
  1105. size_t len = (size_t)
  1106. #ifdef HAVE_SNI
  1107. wolfSSL_SNI_GetRequest(ssl, WOLFSSL_SNI_HOST_NAME, (void **)&servername);
  1108. #else
  1109. 0;
  1110. #endif
  1111. if (0 == len)
  1112. return SSL_TLSEXT_ERR_NOACK; /* client did not provide SNI */
  1113. #if 0 /* WolfSSL does not provide per-session SSL_set_read_ahead() */
  1114. int read_ahead = hctx->conf.ssl_read_ahead;
  1115. int rc = mod_openssl_SNI(hctx, servername, len);
  1116. if (!read_ahead && hctx->conf.ssl_read_ahead)
  1117. SSL_set_read_ahead(ssl, hctx->conf.ssl_read_ahead);
  1118. return rc;
  1119. #else
  1120. return mod_openssl_SNI(hctx, servername, len);
  1121. #endif
  1122. }
  1123. #endif
  1124. #ifdef HAVE_OCSP
  1125. #define OCSP_RESPONSE OcspResponse
  1126. #define OCSP_RESPONSE_free wolfSSL_OCSP_RESPONSE_free
  1127. #define d2i_OCSP_RESPONSE_bio wolfSSL_d2i_OCSP_RESPONSE_bio
  1128. #define d2i_OCSP_RESPONSE wolfSSL_d2i_OCSP_RESPONSE
  1129. #define i2d_OCSP_RESPONSE wolfSSL_i2d_OCSP_RESPONSE
  1130. static buffer *
  1131. mod_openssl_load_stapling_file (const char *file, log_error_st *errh, buffer *b)
  1132. {
  1133. /* load stapling .der into buffer *b only if successful
  1134. *
  1135. * Note: for some TLS libs, the OCSP stapling response is not copied when
  1136. * assigned to a session (and is reasonable since not changed frequently)
  1137. * - BoringSSL SSL_set_ocsp_response()
  1138. * - WolfSSL SSL_set_tlsext_status_ocsp_resp() (differs from OpenSSL API)
  1139. * Therefore, there is a potential race condition if the OCSP response is
  1140. * assigned to the session during the handshake and the Server Hello is
  1141. * partially sent, AND (unlikely, if possible at all), the TLS library is
  1142. * in the middle of reading this OSCP response buffer. If the OCSP response
  1143. * is replaced due to an updated ssl.stapling-file (checked periodically),
  1144. * AND the buffer is resized, this would be a problem. Resizing the buffer
  1145. * is unlikely since updated OSCP response for same certificate are
  1146. * typically the same size with the signature and dates refreshed.
  1147. */
  1148. /* load raw .der file */
  1149. off_t dlen = 1*1024*1024;/*(arbitrary limit: 1 MB file; expect < 1 KB)*/
  1150. char *data = fdevent_load_file(file, &dlen, errh, malloc, free);
  1151. if (NULL == data) return NULL;
  1152. if (NULL == b)
  1153. b = buffer_init();
  1154. else if (b->ptr)
  1155. free(b->ptr);
  1156. b->ptr = data;
  1157. b->used = (uint32_t)dlen;
  1158. b->size = (uint32_t)dlen+1;
  1159. return b;
  1160. }
  1161. static time_t
  1162. mod_openssl_asn1_time_to_posix (ASN1_TIME *asn1time)
  1163. {
  1164. #if LIBWOLFSSL_VERSION_HEX >= 0x04002000
  1165. /* Note: up to at least wolfSSL 4.5.0 (current version as this is written)
  1166. * wolfSSL_ASN1_TIME_diff() is a stub function which always returns 0 */
  1167. /* Note: this does not check for integer overflow of time_t! */
  1168. int day, sec;
  1169. return wolfSSL_ASN1_TIME_diff(&day, &sec, NULL, asn1time)
  1170. ? log_epoch_secs + day*86400 + sec
  1171. : (time_t)-1;
  1172. #else
  1173. UNUSED(asn1time);
  1174. return (time_t)-1;
  1175. #endif
  1176. }
  1177. static time_t
  1178. mod_openssl_ocsp_next_update (plugin_cert *pc)
  1179. {
  1180. #if defined(WOLFSSL_VERSION)
  1181. /* XXX: future TODO */
  1182. UNUSED(pc);
  1183. (void)mod_openssl_asn1_time_to_posix(NULL);
  1184. return (time_t)-1; /*(not implemented)*/
  1185. #else
  1186. buffer *der = pc->ssl_stapling;
  1187. const unsigned char *p = (unsigned char *)der->ptr; /*(p gets modified)*/
  1188. OCSP_RESPONSE *ocsp = d2i_OCSP_RESPONSE(NULL,&p,buffer_string_length(der));
  1189. if (NULL == ocsp) return (time_t)-1;
  1190. OCSP_BASICRESP *bs = OCSP_response_get1_basic(ocsp);
  1191. if (NULL == bs) {
  1192. OCSP_RESPONSE_free(ocsp);
  1193. return (time_t)-1;
  1194. }
  1195. /* XXX: should save and evaluate cert status returned by these calls */
  1196. ASN1_TIME *nextupd = NULL;
  1197. #ifdef WOLFSSL_VERSION /* WolfSSL limitation */
  1198. /* WolfSSL does not provide OCSP_resp_get0() OCSP_single_get0_status() */
  1199. /* (inactive code path; alternative path followed in #if above for WolfSSL)
  1200. * (chain not currently available in mod_openssl when used with WolfSSL)
  1201. * (For WolfSSL, pc->ssl_pemfile_chain might not be filled in with actual
  1202. * chain, but is used to store (buffer **) of DER decoded from PEM certs
  1203. * read from ssl.pemfile, which may be a single cert, pc->ssl_pemfile_x509.
  1204. * The chain is not calculated or filled in if single cert, and neither are
  1205. * (X509 *), though (X509 *) could be temporarily created to calculated
  1206. * (OCSP_CERTID *), which additionally could be calculated once at startup)
  1207. */
  1208. OCSP_CERTID *id = (NULL != pc->ssl_pemfile_chain)
  1209. ? OCSP_cert_to_id(NULL, pc->ssl_pemfile_x509,
  1210. sk_X509_value(pc->ssl_pemfile_chain, 0))
  1211. : NULL;
  1212. if (id == NULL) {
  1213. OCSP_BASICRESP_free(bs);
  1214. OCSP_RESPONSE_free(ocsp);
  1215. return (time_t)-1;
  1216. }
  1217. OCSP_resp_find_status(bs, id, NULL, NULL, NULL, NULL, &nextupd);
  1218. OCSP_CERTID_free(id);
  1219. #else
  1220. OCSP_single_get0_status(OCSP_resp_get0(bs, 0), NULL, NULL, NULL, &nextupd);
  1221. #endif
  1222. time_t t = nextupd ? mod_openssl_asn1_time_to_posix(nextupd) : (time_t)-1;
  1223. /* Note: trust external process which creates ssl.stapling-file to verify
  1224. * (as well as to validate certificate status)
  1225. * future: verify OCSP response here to double-check */
  1226. OCSP_BASICRESP_free(bs);
  1227. OCSP_RESPONSE_free(ocsp);
  1228. return t;
  1229. #endif
  1230. }
  1231. static int
  1232. mod_openssl_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
  1233. {
  1234. buffer *b = mod_openssl_load_stapling_file(pc->ssl_stapling_file->ptr,
  1235. srv->errh, pc->ssl_stapling);
  1236. if (!b) return 0;
  1237. pc->ssl_stapling = b; /*(unchanged unless orig was NULL)*/
  1238. pc->ssl_stapling_loadts = cur_ts;
  1239. pc->ssl_stapling_nextts = mod_openssl_ocsp_next_update(pc);
  1240. if (pc->ssl_stapling_nextts == (time_t)-1) {
  1241. /* "Next Update" might not be provided by OCSP responder
  1242. * Use 3600 sec (1 hour) in that case. */
  1243. /* retry in 1 hour if unable to determine Next Update */
  1244. pc->ssl_stapling_nextts = cur_ts + 3600;
  1245. pc->ssl_stapling_loadts = 0;
  1246. }
  1247. return 1;
  1248. }
  1249. static int
  1250. mod_openssl_refresh_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
  1251. {
  1252. if (pc->ssl_stapling && pc->ssl_stapling_nextts - 256 > cur_ts)
  1253. return 1; /* skip check for refresh unless close to expire */
  1254. struct stat st;
  1255. if (0 != stat(pc->ssl_stapling_file->ptr, &st)
  1256. || st.st_mtime <= pc->ssl_stapling_loadts) {
  1257. if (pc->ssl_stapling_nextts < cur_ts) {
  1258. /* discard expired OCSP stapling response */
  1259. buffer_free(pc->ssl_stapling);
  1260. pc->ssl_stapling = NULL;
  1261. if (pc->must_staple) {
  1262. log_error(srv->errh, __FILE__, __LINE__,
  1263. "certificate marked OCSP Must-Staple, "
  1264. "but OCSP response expired from ssl.stapling-file %s",
  1265. pc->ssl_stapling_file->ptr);
  1266. }
  1267. }
  1268. return 1;
  1269. }
  1270. return mod_openssl_reload_stapling_file(srv, pc, cur_ts);
  1271. }
  1272. static void
  1273. mod_openssl_refresh_stapling_files (server *srv, const plugin_data *p, const time_t cur_ts)
  1274. {
  1275. /* future: might construct array of (plugin_cert *) at startup
  1276. * to avoid the need to search for them here */
  1277. for (int i = 0, used = p->nconfig; i < used; ++i) {
  1278. const config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
  1279. for (; cpv->k_id != -1; ++cpv) {
  1280. if (cpv->k_id != 0) continue; /* k_id == 0 for ssl.pemfile */
  1281. if (cpv->vtype != T_CONFIG_LOCAL) continue;
  1282. plugin_cert *pc = cpv->v.v;
  1283. if (!buffer_string_is_empty(pc->ssl_stapling_file))
  1284. mod_openssl_refresh_stapling_file(srv, pc, cur_ts);
  1285. }
  1286. }
  1287. }
  1288. static int
  1289. mod_openssl_crt_must_staple (const WOLFSSL_X509 *crt)
  1290. {
  1291. /* XXX: TODO: not implemented */
  1292. #if 1
  1293. UNUSED(crt);
  1294. return 0;
  1295. #else
  1296. STACK_OF(ASN1_OBJECT) * const tlsf = (STACK_OF(ASN1_OBJECT)*)
  1297. wolfSSL_X509_get_ext_d2i(crt, NID_tlsfeature, NULL, NULL);
  1298. if (NULL == tlsf) return 0;
  1299. int rc = 0;
  1300. /* wolfSSL_sk_ASN1_INTEGER_num() not implemented */
  1301. /* wolfSSL_sk_ASN1_INTEGER_value() not implemented */
  1302. /* wolfSSL_sk_ASN1_INTEGER_pop_free() not implemented */
  1303. #define wolfSSL_sk_ASN1_INTEGER_num(sk) wolfSSL_sk_num(sk)
  1304. #define wolfSSL_sk_ASN1_INTEGER_value(sk, i) wolfSSL_sk_value(sk, i)
  1305. #define wolfSSL_sk_ASN1_INTEGER_pop_free(sk, fn) wolfSSL_sk_pop_free(sk, fn)
  1306. /* wolfSSL_ASN1_INTEGER_get() is a stub func <= 4.6.0; always returns 0 */
  1307. for (int i = 0; i < wolfSSL_sk_ASN1_INTEGER_num(tlsf); ++i) {
  1308. WOLFSSL_ASN1_INTEGER *ai = wolfSSL_sk_ASN1_INTEGER_value(tlsf, i);
  1309. long tlsextid = wolfSSL_ASN1_INTEGER_get(ai);
  1310. if (tlsextid == 5) { /* 5 = OCSP Must-Staple */
  1311. rc = 1;
  1312. break;
  1313. }
  1314. }
  1315. wolfSSL_sk_ASN1_INTEGER_pop_free(tlsf, wolfSSL_ASN1_INTEGER_free);
  1316. return rc; /* 1 if OCSP Must-Staple found; 0 if not */
  1317. #endif
  1318. }
  1319. #endif /* HAVE_OCSP */
  1320. static plugin_cert *
  1321. network_openssl_load_pemfile (server *srv, const buffer *pemfile, const buffer *privkey, const buffer *ssl_stapling_file)
  1322. {
  1323. if (!mod_openssl_init_once_openssl(srv)) return NULL;
  1324. buffer **ssl_pemfile_chain = NULL;
  1325. buffer *ssl_pemfile_x509 =
  1326. mod_wolfssl_load_pem_file(pemfile->ptr, srv->errh, &ssl_pemfile_chain);
  1327. if (NULL == ssl_pemfile_x509)
  1328. return NULL;
  1329. buffer *ssl_pemfile_pkey =
  1330. mod_wolfssl_evp_pkey_load_pem_file(privkey->ptr, srv->errh);
  1331. if (NULL == ssl_pemfile_pkey) {
  1332. /*buffer_free(ssl_pemfile_x509);*//*(part of chain)*/
  1333. mod_wolfssl_free_der_certs(ssl_pemfile_chain);
  1334. return NULL;
  1335. }
  1336. /* X509_check_private_key() is a stub func (not implemented) in WolfSSL */
  1337. plugin_cert *pc = malloc(sizeof(plugin_cert));
  1338. force_assert(pc);
  1339. pc->ssl_pemfile_pkey = ssl_pemfile_pkey;
  1340. pc->ssl_pemfile_x509 = ssl_pemfile_x509;
  1341. pc->ssl_pemfile_chain= ssl_pemfile_chain;
  1342. pc->ssl_pemfile = pemfile;
  1343. pc->ssl_privkey = privkey;
  1344. pc->ssl_stapling = NULL;
  1345. pc->ssl_stapling_file= ssl_stapling_file;
  1346. pc->ssl_stapling_loadts = 0;
  1347. pc->ssl_stapling_nextts = 0;
  1348. #ifdef HAVE_OCSP
  1349. /*(not implemented for WolfSSL, though could convert the DER to (X509 *),
  1350. * check Must-Staple, and then destroy (X509 *))*/
  1351. (void)mod_openssl_crt_must_staple(NULL);
  1352. pc->must_staple = 0;
  1353. #else
  1354. pc->must_staple = 0;
  1355. #endif
  1356. if (!buffer_string_is_empty(pc->ssl_stapling_file)) {
  1357. #ifdef HAVE_OCSP
  1358. if (!mod_openssl_reload_stapling_file(srv, pc, log_epoch_secs)) {
  1359. /* continue without OCSP response if there is an error */
  1360. }
  1361. #else
  1362. log_error(srv->errh, __FILE__, __LINE__, "SSL:"
  1363. "OCSP stapling not supported; ignoring %s",
  1364. pc->ssl_stapling_file->ptr);
  1365. #endif
  1366. }
  1367. else if (pc->must_staple) {
  1368. log_error(srv->errh, __FILE__, __LINE__,
  1369. "certificate %s marked OCSP Must-Staple, "
  1370. "but ssl.stapling-file not provided", pemfile->ptr);
  1371. }
  1372. return pc;
  1373. }
  1374. #ifdef HAVE_TLS_EXTENSIONS
  1375. #ifdef HAVE_ALPN
  1376. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
  1377. static int
  1378. mod_openssl_acme_tls_1 (SSL *ssl, handler_ctx *hctx)
  1379. {
  1380. buffer * const b = hctx->tmp_buf;
  1381. const buffer * const name = &hctx->r->uri.authority;
  1382. log_error_st * const errh = hctx->r->conf.errh;
  1383. buffer *ssl_pemfile_x509 = NULL;
  1384. buffer *ssl_pemfile_pkey = NULL;
  1385. buffer **ssl_pemfile_chain = NULL;
  1386. size_t len;
  1387. int rc = SSL_TLSEXT_ERR_ALERT_FATAL;
  1388. /* check if acme-tls/1 protocol is enabled (path to dir of cert(s) is set)*/
  1389. if (buffer_string_is_empty(hctx->conf.ssl_acme_tls_1))
  1390. return SSL_TLSEXT_ERR_NOACK; /*(reuse value here for not-configured)*/
  1391. /* check if SNI set server name (required for acme-tls/1 protocol)
  1392. * and perform simple path checks for no '/'
  1393. * and no leading '.' (e.g. ignore "." or ".." or anything beginning '.') */
  1394. if (buffer_string_is_empty(name)) return rc;
  1395. if (NULL != strchr(name->ptr, '/')) return rc;
  1396. if (name->ptr[0] == '.') return rc;
  1397. #if 0
  1398. if (0 != http_request_host_policy(name,hctx->r->conf.http_parseopts,443))
  1399. return rc;
  1400. #endif
  1401. buffer_copy_buffer(b, hctx->conf.ssl_acme_tls_1);
  1402. buffer_append_path_len(b, CONST_BUF_LEN(name));
  1403. len = buffer_string_length(b);
  1404. do {
  1405. buffer_append_string_len(b, CONST_STR_LEN(".crt.pem"));
  1406. ssl_pemfile_x509 =
  1407. mod_wolfssl_load_pem_file(b->ptr, errh, &ssl_pemfile_chain);
  1408. if (NULL == ssl_pemfile_x509) {
  1409. log_error(errh, __FILE__, __LINE__,
  1410. "SSL: Failed to load acme-tls/1 pemfile: %s", b->ptr);
  1411. break;
  1412. }
  1413. buffer_string_set_length(b, len); /*(remove ".crt.pem")*/
  1414. buffer_append_string_len(b, CONST_STR_LEN(".key.pem"));
  1415. ssl_pemfile_pkey = mod_wolfssl_evp_pkey_load_pem_file(b->ptr, errh);
  1416. if (NULL == ssl_pemfile_pkey) {
  1417. log_error(errh, __FILE__, __LINE__,
  1418. "SSL: Failed to load acme-tls/1 pemfile: %s", b->ptr);
  1419. break;
  1420. }
  1421. #if 0 /* redundant with below? */
  1422. if (!X509_check_private_key(ssl_pemfile_x509, ssl_pemfile_pkey)) {
  1423. log_error(errh, __FILE__, __LINE__,
  1424. "SSL: Private key does not match acme-tls/1 "
  1425. "certificate public key, reason: %s %s"
  1426. ERR_error_string(ERR_get_error(), NULL), b->ptr);
  1427. break;
  1428. }
  1429. #endif
  1430. /* first set certificate!
  1431. * setting private key checks whether certificate matches it */
  1432. buffer *cert = ssl_pemfile_x509;
  1433. if (1 != wolfSSL_use_certificate_ASN1(ssl, (unsigned char *)cert->ptr,
  1434. (int)buffer_string_length(cert))){
  1435. log_error(errh, __FILE__, __LINE__,
  1436. "SSL: failed to set acme-tls/1 certificate for TLS server "
  1437. "name %s: %s", name->ptr, ERR_error_string(ERR_get_error(),NULL));
  1438. break;
  1439. }
  1440. if (ssl_pemfile_chain) {
  1441. /* WolfSSL limitation */
  1442. /* WolfSSL does not support setting per-session chain;
  1443. * limitation is to per-CTX chain, and so chain is not provided for
  1444. * "acme-tls/1" (might be non-issue; chain might not be present) */
  1445. }
  1446. buffer *pkey = ssl_pemfile_pkey;
  1447. if (1 != wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char *)pkey->ptr,
  1448. (int)buffer_string_length(pkey),
  1449. WOLFSSL_FILETYPE_ASN1)) {
  1450. log_error(errh, __FILE__, __LINE__,
  1451. "SSL: failed to set acme-tls/1 private key for TLS server "
  1452. "name %s: %s", name->ptr, ERR_error_string(ERR_get_error(),NULL));
  1453. break;
  1454. }
  1455. hctx->conf.ssl_verifyclient_enforce = 0;
  1456. wolfSSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
  1457. rc = SSL_TLSEXT_ERR_OK;
  1458. } while (0);
  1459. if (ssl_pemfile_pkey) buffer_free(ssl_pemfile_pkey);
  1460. /*if (ssl_pemfile_x509) buffer_free(ssl_pemfile_x509);*//*(part of chain)*/
  1461. mod_wolfssl_free_der_certs(ssl_pemfile_chain);
  1462. return rc;
  1463. }
  1464. enum {
  1465. MOD_OPENSSL_ALPN_HTTP11 = 1
  1466. ,MOD_OPENSSL_ALPN_HTTP10 = 2
  1467. ,MOD_OPENSSL_ALPN_H2 = 3
  1468. ,MOD_OPENSSL_ALPN_ACME_TLS_1 = 4
  1469. };
  1470. /* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
  1471. static int
  1472. mod_openssl_alpn_select_cb (SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
  1473. {
  1474. handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
  1475. unsigned short proto;
  1476. UNUSED(arg);
  1477. for (unsigned int i = 0, n; i < inlen; i += n) {
  1478. n = in[i++];
  1479. if (i+n > inlen || 0 == n) break;
  1480. switch (n) {
  1481. case 2: /* "h2" */
  1482. if (in[i] == 'h' && in[i+1] == '2') {
  1483. if (!hctx->r->conf.h2proto) continue;
  1484. proto = MOD_OPENSSL_ALPN_H2;
  1485. hctx->r->http_version = HTTP_VERSION_2;
  1486. break;
  1487. }
  1488. continue;
  1489. case 8: /* "http/1.1" "http/1.0" */
  1490. if (0 == memcmp(in+i, "http/1.", 7)) {
  1491. if (in[i+7] == '1') {
  1492. proto = MOD_OPENSSL_ALPN_HTTP11;
  1493. break;
  1494. }
  1495. if (in[i+7] == '0') {
  1496. proto = MOD_OPENSSL_ALPN_HTTP10;
  1497. break;
  1498. }
  1499. }
  1500. continue;
  1501. case 10: /* "acme-tls/1" */
  1502. if (0 == memcmp(in+i, "acme-tls/1", 10)) {
  1503. int rc = mod_openssl_acme_tls_1(ssl, hctx);
  1504. if (rc == SSL_TLSEXT_ERR_OK) {
  1505. proto = MOD_OPENSSL_ALPN_ACME_TLS_1;
  1506. break;
  1507. }
  1508. /* (use SSL_TLSEXT_ERR_NOACK for not-configured) */
  1509. if (rc == SSL_TLSEXT_ERR_NOACK) continue;
  1510. return rc;
  1511. }
  1512. continue;
  1513. default:
  1514. continue;
  1515. }
  1516. hctx->alpn = proto;
  1517. *out = in+i;
  1518. *outlen = n;
  1519. return SSL_TLSEXT_ERR_OK;
  1520. }
  1521. return SSL_TLSEXT_ERR_NOACK;
  1522. }
  1523. #endif /* TLSEXT_TYPE_application_layer_protocol_negotiation */
  1524. #endif /* HAVE_ALPN */
  1525. #endif /* HAVE_TLS_EXTENSIONS */
  1526. static int
  1527. mod_openssl_ssl_conf_cmd (server *srv, plugin_config_socket *s);
  1528. #ifndef NO_DH
  1529. #include <wolfssl/openssl/dh.h>
  1530. /* wolfSSL provides wolfSSL_DH_set0_pqg() for
  1531. * Apache w/ OPENSSL_VERSION_NUMBER >= 0x10100000L
  1532. * but does not provide most other openssl 1.1.0+ interfaces
  1533. * and get_dh2048() might not be necessary if wolfSSL defines
  1534. * HAVE_TLS_EXTENSIONS HAVE_DH_DEFAULT_PARAMS HAVE_FFDHE HAVE_SUPPORTED_CURVES*/
  1535. #define DH_set0_pqg(dh, dh_p, NULL, dh_g) \
  1536. ((dh)->p = (dh_p), (dh)->g = (dh_g), (dh_p) != NULL && (dh_g) != NULL)
  1537. /* https://tools.ietf.org/html/rfc7919#appendix-A.1
  1538. * A.1. ffdhe2048
  1539. *
  1540. * https://ssl-config.mozilla.org/ffdhe2048.txt
  1541. * C code generated with: openssl dhparam -C -in ffdhe2048.txt
  1542. */
  1543. static DH *get_dh2048(void)
  1544. {
  1545. static unsigned char dhp_2048[] = {
  1546. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8,
  1547. 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, 0xAF, 0xDC, 0x56, 0x20,
  1548. 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D,
  1549. 0x36, 0x95, 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
  1550. 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, 0x7D, 0x2F,
  1551. 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02,
  1552. 0xAE, 0xC4, 0x61, 0x7A, 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD,
  1553. 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
  1554. 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57,
  1555. 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, 0x98, 0x4F, 0x0C, 0x70,
  1556. 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF,
  1557. 0xE8, 0x72, 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
  1558. 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, 0xBC, 0x0A,
  1559. 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B,
  1560. 0xB2, 0xC8, 0xE3, 0xFB, 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7,
  1561. 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
  1562. 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07,
  1563. 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, 0x9E, 0x02, 0xFC, 0xE1,
  1564. 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34,
  1565. 0x2F, 0x61, 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
  1566. 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, 0xC3, 0xFE,
  1567. 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC,
  1568. 0x2E, 0xC2, 0x20, 0x05, 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16,
  1569. 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
  1570. 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, 0xFF, 0xFF,
  1571. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  1572. };
  1573. static unsigned char dhg_2048[] = {
  1574. 0x02
  1575. };
  1576. DH *dh = DH_new();
  1577. BIGNUM *p, *g;
  1578. if (dh == NULL)
  1579. return NULL;
  1580. p = BN_bin2bn(dhp_2048, sizeof(dhp_2048), NULL);
  1581. g = BN_bin2bn(dhg_2048, sizeof(dhg_2048), NULL);
  1582. if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
  1583. DH_free(dh);
  1584. BN_free(p);
  1585. BN_free(g);
  1586. return NULL;
  1587. }
  1588. return dh;
  1589. }
  1590. #endif
  1591. static int
  1592. mod_openssl_ssl_conf_curves(server *srv, plugin_config_socket *s, const buffer *ssl_ec_curve)
  1593. {
  1594. int nid = 0;
  1595. /* Support for Elliptic-Curve Diffie-Hellman key exchange */
  1596. if (!buffer_string_is_empty(ssl_ec_curve)) {
  1597. /* OpenSSL only supports the "named curves"
  1598. * from RFC 4492, section 5.1.1. */
  1599. nid = wolfSSL_OBJ_sn2nid((char *) ssl_ec_curve->ptr);
  1600. if (nid == 0) {
  1601. log_error(srv->errh, __FILE__, __LINE__,
  1602. "SSL: Unknown curve name %s", ssl_ec_curve->ptr);
  1603. return 0;
  1604. }
  1605. }
  1606. else {
  1607. /* Default curve */
  1608. nid = wolfSSL_OBJ_sn2nid("prime256v1");
  1609. }
  1610. if (nid) {
  1611. EC_KEY *ecdh;
  1612. ecdh = EC_KEY_new_by_curve_name(nid);
  1613. if (ecdh == NULL) {
  1614. log_error(srv->errh, __FILE__, __LINE__,
  1615. "SSL: Unable to create curve %s", ssl_ec_curve->ptr);
  1616. return 0;
  1617. }
  1618. wolfSSL_SSL_CTX_set_tmp_ecdh(s->ssl_ctx, ecdh);
  1619. SSL_CTX_set_options(s->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
  1620. EC_KEY_free(ecdh);
  1621. }
  1622. return 1;
  1623. }
  1624. static int
  1625. network_init_ssl (server *srv, plugin_config_socket *s, plugin_data *p)
  1626. {
  1627. /* load SSL certificates */
  1628. #ifndef SSL_OP_NO_COMPRESSION
  1629. #define SSL_OP_NO_COMPRESSION 0
  1630. #endif
  1631. long ssloptions = SSL_OP_ALL
  1632. | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
  1633. | SSL_OP_NO_COMPRESSION;
  1634. #if LIBWOLFSSL_VERSION_HEX >= 0x04002000
  1635. s->ssl_ctx = (!s->ssl_use_sslv2 && !s->ssl_use_sslv3)
  1636. ? SSL_CTX_new(TLS_server_method())
  1637. : SSL_CTX_new(SSLv23_server_method());
  1638. #else
  1639. s->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
  1640. #endif
  1641. if (NULL == s->ssl_ctx) {
  1642. log_error(srv->errh, __FILE__, __LINE__,
  1643. "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
  1644. return -1;
  1645. }
  1646. #ifdef SSL_OP_NO_RENEGOTIATION /* openssl 1.1.0 */
  1647. if (s->ssl_disable_client_renegotiation)
  1648. ssloptions |= SSL_OP_NO_RENEGOTIATION;
  1649. #endif
  1650. /* completely useless identifier;
  1651. * required for client cert verification to work with sessions */
  1652. if (0 == SSL_CTX_set_session_id_context(
  1653. s->ssl_ctx,(const unsigned char*)CONST_STR_LEN("lighttpd"))){
  1654. log_error(srv->errh, __FILE__, __LINE__,
  1655. "SSL: failed to set session context: %s",
  1656. ERR_error_string(ERR_get_error(), NULL));
  1657. return -1;
  1658. }
  1659. #if !defined(NO_SESSION_CACHE)
  1660. const int disable_sess_cache =
  1661. srv->srvconf.feature_flags
  1662. && !config_plugin_value_tobool(
  1663. array_get_element_klen(srv->srvconf.feature_flags,
  1664. CONST_STR_LEN("ssl.session-cache")), 0);
  1665. if (disable_sess_cache)
  1666. /* disable session cache; session tickets are preferred */
  1667. SSL_CTX_set_session_cache_mode(s->ssl_ctx,
  1668. SSL_SESS_CACHE_OFF
  1669. | SSL_SESS_CACHE_NO_AUTO_CLEAR
  1670. | SSL_SESS_CACHE_NO_INTERNAL);
  1671. #endif
  1672. if (s->ssl_empty_fragments) {
  1673. #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
  1674. ssloptions &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
  1675. #else
  1676. ssloptions &= ~0x00000800L; /* hardcode constant */
  1677. log_error(srv->errh, __FILE__, __LINE__,
  1678. "WARNING: SSL: 'insert empty fragments' not supported by the "
  1679. "openssl version used to compile lighttpd with");
  1680. #endif
  1681. }
  1682. SSL_CTX_set_options(s->ssl_ctx, ssloptions);
  1683. SSL_CTX_set_info_callback(s->ssl_ctx, ssl_info_callback);
  1684. /*(wolfSSL does not support SSLv2)*/
  1685. if (!s->ssl_use_sslv3 && 0 != SSL_OP_NO_SSLv3) {
  1686. /* disable SSLv3 */
  1687. if ((SSL_OP_NO_SSLv3
  1688. & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv3))
  1689. != SSL_OP_NO_SSLv3) {
  1690. log_error(srv->errh, __FILE__, __LINE__,
  1691. "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
  1692. return -1;
  1693. }
  1694. }
  1695. if (!buffer_string_is_empty(s->ssl_cipher_list)) {
  1696. /* Disable support for low encryption ciphers */
  1697. if (SSL_CTX_set_cipher_list(s->ssl_ctx,s->ssl_cipher_list->ptr)!=1){
  1698. log_error(srv->errh, __FILE__, __LINE__,
  1699. "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
  1700. return -1;
  1701. }
  1702. if (s->ssl_honor_cipher_order) {
  1703. SSL_CTX_set_options(s->ssl_ctx,SSL_OP_CIPHER_SERVER_PREFERENCE);
  1704. }
  1705. }
  1706. #ifdef SSL_OP_PRIORITIZE_CHACHA /*(openssl 1.1.1)*/
  1707. if (s->ssl_honor_cipher_order)
  1708. SSL_CTX_set_options(s->ssl_ctx, SSL_OP_PRIORITIZE_CHACHA);
  1709. #endif
  1710. #ifndef NO_DH
  1711. {
  1712. DH *dh;
  1713. /* Support for Diffie-Hellman key exchange */
  1714. if (!buffer_string_is_empty(s->ssl_dh_file)) {
  1715. const char *fn = s->ssl_dh_file->ptr;
  1716. off_t dlen = 1*1024*1024;/*(arbitrary limit: 1 MB; expect < 1 KB)*/
  1717. char *data = fdevent_load_file(fn, &dlen, srv->errh, malloc, free);
  1718. int rc = (NULL != data) ? 0 : -1;
  1719. if (0 == rc)
  1720. wolfSSL_CTX_SetTmpDH_buffer(s->ssl_ctx, (unsigned char *)data,
  1721. (long)dlen, WOLFSSL_FILETYPE_PEM);
  1722. if (dlen) safe_memclear(data, dlen);
  1723. free(data);
  1724. if (rc < 0) {
  1725. log_error(srv->errh, __FILE__, __LINE__,
  1726. "SSL: Unable to read DH params from file %s",
  1727. s->ssl_dh_file->ptr);
  1728. return -1;
  1729. }
  1730. }
  1731. else {
  1732. dh = get_dh2048();
  1733. if (dh == NULL) {
  1734. log_error(srv->errh, __FILE__, __LINE__,
  1735. "SSL: get_dh2048() failed");
  1736. return -1;
  1737. }
  1738. SSL_CTX_set_tmp_dh(s->ssl_ctx,dh);
  1739. DH_free(dh);
  1740. }
  1741. SSL_CTX_set_options(s->ssl_ctx,SSL_OP_SINGLE_DH_USE);
  1742. }
  1743. #else
  1744. if (!buffer_string_is_empty(s->ssl_dh_file)) {
  1745. log_error(srv->errh, __FILE__, __LINE__,
  1746. "SSL: openssl compiled without DH support, "
  1747. "can't load parameters from %s", s->ssl_dh_file->ptr);
  1748. }
  1749. #endif
  1750. if (!mod_openssl_ssl_conf_curves(srv, s, s->ssl_ec_curve))
  1751. return -1;
  1752. #ifdef HAVE_SESSION_TICKET
  1753. wolfSSL_CTX_set_tlsext_ticket_key_cb(s->ssl_ctx, ssl_tlsext_ticket_key_cb);
  1754. #endif
  1755. #ifdef HAVE_OCSP
  1756. wolfSSL_CTX_set_tlsext_status_cb(s->ssl_ctx, ssl_tlsext_status_cb);
  1757. #endif
  1758. /* load all ssl.ca-files specified in the config into each SSL_CTX
  1759. * XXX: This might be a bit excessive, but are all trusted CAs
  1760. * TODO: prefer to load on-demand in mod_openssl_cert_cb()
  1761. * for openssl >= 1.0.2 */
  1762. if (!mod_wolfssl_load_ca_files(s->ssl_ctx, p, srv))
  1763. return -1;
  1764. if (s->ssl_verifyclient) {
  1765. if (NULL == s->ssl_ca_file) {
  1766. log_error(srv->errh, __FILE__, __LINE__,
  1767. "SSL: You specified ssl.verifyclient.activate "
  1768. "but no ssl.ca-file");
  1769. return -1;
  1770. }
  1771. #ifndef OPENSSL_ALL
  1772. log_error(srv->errh, __FILE__, __LINE__,
  1773. "SSL: You specified ssl.verifyclient.activate "
  1774. "but wolfssl library built without necessary support");
  1775. return -1;
  1776. #else
  1777. /* Before wolfssl 4.6.0, wolfSSL_dup_CA_list() is a stub function
  1778. * which returns NULL, so DN names in cert request are not set here.
  1779. * (A patch has been submitted to WolfSSL add is part of 4.6.0)
  1780. * https://github.com/wolfSSL/wolfssl/pull/3098 */
  1781. STACK_OF(X509_NAME) * const cert_names = s->ssl_ca_dn_file
  1782. ? s->ssl_ca_dn_file
  1783. : s->ssl_ca_file->names;
  1784. wolfSSL_CTX_set_client_CA_list(s->ssl_ctx,
  1785. wolfSSL_dup_CA_list(cert_names));
  1786. int mode = SSL_VERIFY_PEER;
  1787. if (s->ssl_verifyclient_enforce) {
  1788. mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
  1789. }
  1790. wolfSSL_CTX_set_verify(s->ssl_ctx, mode, verify_callback);
  1791. wolfSSL_CTX_set_verify_depth(s->ssl_ctx,
  1792. s->ssl_verifyclient_depth + 1);
  1793. #endif
  1794. if (!buffer_string_is_empty(s->ssl_ca_crl_file)) {
  1795. if (!mod_wolfssl_load_cacrls(s->ssl_ctx,s->ssl_ca_crl_file,srv))
  1796. return -1;
  1797. }
  1798. }
  1799. if (1 != mod_wolfssl_CTX_use_certificate_chain_file(
  1800. s->ssl_ctx, s->pc->ssl_pemfile->ptr, srv->errh))
  1801. return -1;
  1802. buffer *k = s->pc->ssl_pemfile_pkey;
  1803. if (1 != wolfSSL_CTX_use_PrivateKey_buffer(s->ssl_ctx,
  1804. (unsigned char *)k->ptr,
  1805. (int)buffer_string_length(k),
  1806. WOLFSSL_FILETYPE_ASN1)) {
  1807. log_error(srv->errh, __FILE__, __LINE__,
  1808. "SSL: %s %s %s", ERR_error_string(ERR_get_error(), NULL),
  1809. s->pc->ssl_pemfile->ptr, s->pc->ssl_privkey->ptr);
  1810. return -1;
  1811. }
  1812. if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
  1813. log_error(srv->errh, __FILE__, __LINE__,
  1814. "SSL: Private key does not match the certificate public key, "
  1815. "reason: %s %s %s", ERR_error_string(ERR_get_error(), NULL),
  1816. s->pc->ssl_pemfile->ptr, s->pc->ssl_privkey->ptr);
  1817. return -1;
  1818. }
  1819. SSL_CTX_set_default_read_ahead(s->ssl_ctx, s->ssl_read_ahead);
  1820. wolfSSL_CTX_set_mode(s->ssl_ctx,
  1821. SSL_MODE_ENABLE_PARTIAL_WRITE);
  1822. wolfSSL_CTX_set_mode(s->ssl_ctx, /*(wolfSSL default mode)*/
  1823. WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  1824. #ifdef wolfSSL_SSL_MODE_RELEASE_BUFFERS
  1825. wolfSSL_CTX_set_mode(s->ssl_ctx, /*(not currently implemented)*/
  1826. wolfSSL_SSL_MODE_RELEASE_BUFFERS);
  1827. #endif
  1828. #ifdef HAVE_TLS_EXTENSIONS
  1829. /*(wolfSSL preprocessor defines are obnoxious)*/
  1830. /*(code should be HAVE_SNI, but is hidden by OPENSSL_ALL
  1831. * even though the comment in wolfssl code on the #endif
  1832. * says (OPENSSL_ALL
  1833. * || (OPENSSL_EXTRA
  1834. * && (HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_LIGHTY)))
  1835. * and sniRecvCb sniRecvCbArg are hidden by *different* set of defines
  1836. * in wolfssl/internal.h)
  1837. * Note: wolfSSL SNI callbacks members not present unless wolfSSL is
  1838. * built OPENSSL_ALL or some additional combination of preprocessor
  1839. * defines. The following should work with more recent wolfSSL versions
  1840. * (and HAVE_LIGHTY is not sufficient in wolfssl <= 4.5.0) */
  1841. #if defined(OPENSSL_ALL) \
  1842. || (defined(OPENSSL_EXTRA) \
  1843. && (defined(HAVE_STUNNEL) \
  1844. || defined(WOLFSSL_NGINX) \
  1845. || defined(WOLFSSL_HAPROXY)))
  1846. #else
  1847. #undef HAVE_SNI
  1848. #endif
  1849. #ifdef HAVE_SNI
  1850. wolfSSL_CTX_set_servername_callback(
  1851. s->ssl_ctx, network_ssl_servername_callback);
  1852. wolfSSL_CTX_set_servername_arg(s->ssl_ctx, srv);
  1853. #else
  1854. log_error(srv->errh, __FILE__, __LINE__,
  1855. "SSL: WARNING: SNI callbacks *crippled* in wolfSSL library build");
  1856. UNUSED(network_ssl_servername_callback);
  1857. #endif
  1858. #ifdef HAVE_ALPN
  1859. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
  1860. SSL_CTX_set_alpn_select_cb(s->ssl_ctx,mod_openssl_alpn_select_cb,NULL);
  1861. #endif
  1862. #endif
  1863. #endif
  1864. if (!s->ssl_use_sslv3 && !s->ssl_use_sslv2
  1865. && wolfSSL_CTX_SetMinVersion(s->ssl_ctx, WOLFSSL_TLSV1_2)
  1866. != WOLFSSL_SUCCESS)
  1867. return -1;
  1868. if (s->ssl_conf_cmd && s->ssl_conf_cmd->used) {
  1869. if (0 != mod_openssl_ssl_conf_cmd(srv, s)) return -1;
  1870. }
  1871. return 0;
  1872. }
  1873. static int
  1874. mod_openssl_set_defaults_sockets(server *srv, plugin_data *p)
  1875. {
  1876. static const config_plugin_keys_t cpk[] = {
  1877. { CONST_STR_LEN("ssl.engine"),
  1878. T_CONFIG_BOOL,
  1879. T_CONFIG_SCOPE_CONNECTION }
  1880. ,{ CONST_STR_LEN("ssl.cipher-list"),
  1881. T_CONFIG_STRING,
  1882. T_CONFIG_SCOPE_CONNECTION }
  1883. ,{ CONST_STR_LEN("ssl.honor-cipher-order"),
  1884. T_CONFIG_BOOL,
  1885. T_CONFIG_SCOPE_CONNECTION }
  1886. ,{ CONST_STR_LEN("ssl.dh-file"),
  1887. T_CONFIG_STRING,
  1888. T_CONFIG_SCOPE_CONNECTION }
  1889. ,{ CONST_STR_LEN("ssl.ec-curve"),
  1890. T_CONFIG_STRING,
  1891. T_CONFIG_SCOPE_CONNECTION }
  1892. ,{ CONST_STR_LEN("ssl.openssl.ssl-conf-cmd"),
  1893. T_CONFIG_ARRAY_KVSTRING,
  1894. T_CONFIG_SCOPE_CONNECTION }
  1895. ,{ CONST_STR_LEN("ssl.pemfile"), /* included to process global scope */
  1896. T_CONFIG_STRING,
  1897. T_CONFIG_SCOPE_CONNECTION }
  1898. ,{ CONST_STR_LEN("ssl.empty-fragments"),
  1899. T_CONFIG_BOOL,
  1900. T_CONFIG_SCOPE_CONNECTION }
  1901. ,{ CONST_STR_LEN("ssl.use-sslv2"),
  1902. T_CONFIG_BOOL,
  1903. T_CONFIG_SCOPE_CONNECTION }
  1904. ,{ CONST_STR_LEN("ssl.use-sslv3"),
  1905. T_CONFIG_BOOL,
  1906. T_CONFIG_SCOPE_CONNECTION }
  1907. ,{ CONST_STR_LEN("ssl.stek-file"),
  1908. T_CONFIG_STRING,
  1909. T_CONFIG_SCOPE_SERVER }
  1910. ,{ NULL, 0,
  1911. T_CONFIG_UNSET,
  1912. T_CONFIG_SCOPE_UNSET }
  1913. };
  1914. /* WolfSSL does not have mapping for "HIGH" */
  1915. /* cipher list is (current) output of "openssl ciphers HIGH" */
  1916. 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 };
  1917. p->ssl_ctxs = calloc(srv->config_context->used, sizeof(plugin_ssl_ctx));
  1918. force_assert(p->ssl_ctxs);
  1919. int rc = HANDLER_GO_ON;
  1920. plugin_data_base srvplug;
  1921. memset(&srvplug, 0, sizeof(srvplug));
  1922. plugin_data_base * const ps = &srvplug;
  1923. if (!config_plugin_values_init(srv, ps, cpk, "mod_openssl"))
  1924. return HANDLER_ERROR;
  1925. plugin_config_socket defaults;
  1926. memset(&defaults, 0, sizeof(defaults));
  1927. defaults.ssl_honor_cipher_order = 1;
  1928. defaults.ssl_cipher_list = &default_ssl_cipher_list;
  1929. /* process and validate config directives for global and $SERVER["socket"]
  1930. * (init i to 0 if global context; to 1 to skip empty global context) */
  1931. for (int i = !ps->cvlist[0].v.u2[1]; i < ps->nconfig; ++i) {
  1932. config_cond_info cfginfo;
  1933. config_get_config_cond_info(&cfginfo, (uint32_t)ps->cvlist[i].k_id);
  1934. int is_socket_scope = (0 == i || cfginfo.comp == COMP_SERVER_SOCKET);
  1935. int count_not_engine = 0;
  1936. plugin_config_socket conf;
  1937. memcpy(&conf, &defaults, sizeof(conf));
  1938. /*(preserve prior behavior; not inherited)*/
  1939. /*(forcing inheritance might break existing configs where SSL is enabled
  1940. * by default in the global scope, but not $SERVER["socket"]=="*:80") */
  1941. conf.ssl_enabled = 0;
  1942. config_plugin_value_t *cpv = ps->cvlist + ps->cvlist[i].v.u2[0];
  1943. for (; -1 != cpv->k_id; ++cpv) {
  1944. /* ignore ssl.pemfile (k_id=6); included to process global scope */
  1945. if (!is_socket_scope && cpv->k_id != 6) {
  1946. log_error(srv->errh, __FILE__, __LINE__,
  1947. "%s is valid only in global scope or "
  1948. "$SERVER[\"socket\"] condition", cpk[cpv->k_id].k);
  1949. continue;
  1950. }
  1951. ++count_not_engine;
  1952. switch (cpv->k_id) {
  1953. case 0: /* ssl.engine */
  1954. conf.ssl_enabled = (0 != cpv->v.u);
  1955. --count_not_engine;
  1956. break;
  1957. case 1: /* ssl.cipher-list */
  1958. conf.ssl_cipher_list = cpv->v.b;
  1959. break;
  1960. case 2: /* ssl.honor-cipher-order */
  1961. conf.ssl_honor_cipher_order = (0 != cpv->v.u);
  1962. break;
  1963. case 3: /* ssl.dh-file */
  1964. conf.ssl_dh_file = cpv->v.b;
  1965. break;
  1966. case 4: /* ssl.ec-curve */
  1967. conf.ssl_ec_curve = cpv->v.b;
  1968. break;
  1969. case 5: /* ssl.openssl.ssl-conf-cmd */
  1970. *(const array **)&conf.ssl_conf_cmd = cpv->v.a;
  1971. break;
  1972. case 6: /* ssl.pemfile */
  1973. /* ignore here; included to process global scope when
  1974. * ssl.pemfile is set, but ssl.engine is not "enable" */
  1975. break;
  1976. case 7: /* ssl.empty-fragments */
  1977. conf.ssl_empty_fragments = (0 != cpv->v.u);
  1978. log_error(srv->errh, __FILE__, __LINE__, "SSL: "
  1979. "ssl.empty-fragments is deprecated and will soon be "
  1980. "removed. It is disabled by default.");
  1981. if (conf.ssl_empty_fragments)
  1982. log_error(srv->errh, __FILE__, __LINE__, "SSL: "
  1983. "If needed, use: ssl.openssl.ssl-conf-cmd = "
  1984. "(\"Options\" => \"EmptyFragments\")");
  1985. log_error(srv->errh, __FILE__, __LINE__, "SSL: "
  1986. "ssl.empty-fragments is a "
  1987. "counter-measure against a SSL 3.0/TLS 1.0 protocol "
  1988. "vulnerability affecting CBC ciphers, which cannot be handled"
  1989. " by some broken (Microsoft) SSL implementations.");
  1990. break;
  1991. case 8: /* ssl.use-sslv2 */
  1992. conf.ssl_use_sslv2 = (0 != cpv->v.u);
  1993. log_error(srv->errh, __FILE__, __LINE__, "SSL: "
  1994. "ssl.use-sslv2 is deprecated and will soon be removed. "
  1995. "It is disabled by default. "
  1996. "Many modern TLS libraries no longer support SSLv2.");
  1997. break;
  1998. case 9: /* ssl.use-sslv3 */
  1999. conf.ssl_use_sslv3 = (0 != cpv->v.u);
  2000. log_error(srv->errh, __FILE__, __LINE__, "SSL: "
  2001. "ssl.use-sslv3 is deprecated and will soon be removed. "
  2002. "It is disabled by default. "
  2003. "Many modern TLS libraries no longer support SSLv3.");
  2004. if (conf.ssl_use_sslv3)
  2005. log_error(srv->errh, __FILE__, __LINE__, "SSL: "
  2006. "If needed, use: ssl.openssl.ssl-conf-cmd = "
  2007. "(\"MinProtocol\" => \"SSLv3\")");
  2008. break;
  2009. case 10:/* ssl.stek-file */
  2010. if (!buffer_is_empty(cpv->v.b))
  2011. p->ssl_stek_file = cpv->v.b->ptr;
  2012. break;
  2013. default:/* should not happen */
  2014. break;
  2015. }
  2016. }
  2017. if (HANDLER_GO_ON != rc) break;
  2018. if (0 == i) memcpy(&defaults, &conf, sizeof(conf));
  2019. if (0 != i && !conf.ssl_enabled) continue;
  2020. /* fill plugin_config_socket with global context then $SERVER["socket"]
  2021. * only for directives directly in current $SERVER["socket"] condition*/
  2022. /*conf.pc = p->defaults.pc;*/
  2023. conf.ssl_ca_file = p->defaults.ssl_ca_file;
  2024. conf.ssl_ca_dn_file = p->defaults.ssl_ca_dn_file;
  2025. conf.ssl_ca_crl_file = p->defaults.ssl_ca_crl_file;
  2026. conf.ssl_verifyclient = p->defaults.ssl_verifyclient;
  2027. conf.ssl_verifyclient_enforce = p->defaults.ssl_verifyclient_enforce;
  2028. conf.ssl_verifyclient_depth = p->defaults.ssl_verifyclient_depth;
  2029. conf.ssl_read_ahead = p->defaults.ssl_read_ahead;
  2030. int sidx = ps->cvlist[i].k_id;
  2031. for (int j = !p->cvlist[0].v.u2[1]; j < p->nconfig; ++j) {
  2032. if (p->cvlist[j].k_id != sidx) continue;
  2033. /*if (0 == sidx) break;*//*(repeat to get ssl_pemfile,ssl_privkey)*/
  2034. cpv = p->cvlist + p->cvlist[j].v.u2[0];
  2035. for (; -1 != cpv->k_id; ++cpv) {
  2036. ++count_not_engine;
  2037. switch (cpv->k_id) {
  2038. case 0: /* ssl.pemfile */
  2039. if (cpv->vtype == T_CONFIG_LOCAL)
  2040. conf.pc = cpv->v.v;
  2041. break;
  2042. case 2: /* ssl.ca-file */
  2043. if (cpv->vtype == T_CONFIG_LOCAL)
  2044. conf.ssl_ca_file = cpv->v.v;
  2045. break;
  2046. case 3: /* ssl.ca-dn-file */
  2047. if (cpv->vtype == T_CONFIG_LOCAL)
  2048. conf.ssl_ca_dn_file = cpv->v.v;
  2049. break;
  2050. case 4: /* ssl.ca-crl-file */
  2051. conf.ssl_ca_crl_file = cpv->v.b;
  2052. break;
  2053. case 5: /* ssl.read-ahead */
  2054. conf.ssl_read_ahead = (0 != cpv->v.u);
  2055. break;
  2056. case 6: /* ssl.disable-client-renegotiation */
  2057. conf.ssl_disable_client_renegotiation = (0 != cpv->v.u);
  2058. break;
  2059. case 7: /* ssl.verifyclient.activate */
  2060. conf.ssl_verifyclient = (0 != cpv->v.u);
  2061. break;
  2062. case 8: /* ssl.verifyclient.enforce */
  2063. conf.ssl_verifyclient_enforce = (0 != cpv->v.u);
  2064. break;
  2065. case 9: /* ssl.verifyclient.depth */
  2066. conf.ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
  2067. break;
  2068. default:
  2069. break;
  2070. }
  2071. }
  2072. break;
  2073. }
  2074. if (NULL == conf.pc) {
  2075. if (0 == i && !conf.ssl_enabled) continue;
  2076. if (0 != i) {
  2077. /* inherit ssl settings from global scope
  2078. * (if only ssl.engine = "enable" and no other ssl.* settings)
  2079. * (This is for convenience when defining both IPv4 and IPv6
  2080. * and desiring to inherit the ssl config from global context
  2081. * without having to duplicate the directives)*/
  2082. if (count_not_engine
  2083. || (conf.ssl_enabled && NULL == p->ssl_ctxs[0].ssl_ctx)) {
  2084. log_error(srv->errh, __FILE__, __LINE__,
  2085. "ssl.pemfile has to be set in same $SERVER[\"socket\"] scope "
  2086. "as other ssl.* directives, unless only ssl.engine is set, "
  2087. "inheriting ssl.* from global scope");
  2088. rc = HANDLER_ERROR;
  2089. continue;
  2090. }
  2091. plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
  2092. *s = *p->ssl_ctxs;/*(copy struct of ssl_ctx from global scope)*/
  2093. continue;
  2094. }
  2095. /* PEM file is required */
  2096. log_error(srv->errh, __FILE__, __LINE__,
  2097. "ssl.pemfile has to be set when ssl.engine = \"enable\"");
  2098. rc = HANDLER_ERROR;
  2099. continue;
  2100. }
  2101. /* configure ssl_ctx for socket */
  2102. /*conf.ssl_ctx = NULL;*//*(filled by network_init_ssl() even on error)*/
  2103. if (0 == network_init_ssl(srv, &conf, p)) {
  2104. plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
  2105. s->ssl_ctx = conf.ssl_ctx;
  2106. }
  2107. else {
  2108. SSL_CTX_free(conf.ssl_ctx);
  2109. rc = HANDLER_ERROR;
  2110. }
  2111. }
  2112. #ifdef HAVE_SESSION_TICKET
  2113. if (rc == HANDLER_GO_ON && ssl_is_init)
  2114. mod_openssl_session_ticket_key_check(p, log_epoch_secs);
  2115. #endif
  2116. free(srvplug.cvlist