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