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