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