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