diff --git a/READMEs/README.lwsws.md b/READMEs/README.lwsws.md index c95a7eec6..b36b38851 100644 --- a/READMEs/README.lwsws.md +++ b/READMEs/README.lwsws.md @@ -259,6 +259,8 @@ See also "rawonly" below. - "`ssl-option-clear'": "" Clears the SSL option flag value for the vhost. It may be used multiple times and OR's the flags together. + - "`ssl-client-option-set`" and "`ssl-client-option-clear`" work the same way for the vhost Client SSL context + - "`headers':: [{ "header1": "h1value", "header2": "h2value" }] allows you to set arbitrary headers on every file served by the vhost diff --git a/include/libwebsockets/lws-context-vhost.h b/include/libwebsockets/lws-context-vhost.h index 44a6ed91b..2dbf6eb3d 100644 --- a/include/libwebsockets/lws-context-vhost.h +++ b/include/libwebsockets/lws-context-vhost.h @@ -308,9 +308,9 @@ struct lws_context_creation_info { * like this for compatibility with the original short version, * this is unsigned int length. */ long ssl_options_set; - /**< VHOST: Any bits set here will be set as SSL options */ + /**< VHOST: Any bits set here will be set as server SSL options */ long ssl_options_clear; - /**< VHOST: Any bits set here will be cleared as SSL options */ + /**< VHOST: Any bits set here will be cleared as server SSL options */ unsigned short ws_ping_pong_interval; /**< CONTEXT: 0 for none, else interval in seconds between sending * PINGs on idle websocket connections. When the PING is sent, @@ -486,6 +486,12 @@ struct lws_context_creation_info { * like this for compatibility with the original short version: * this is unsigned int length. */ + long ssl_client_options_set; + /**< VHOST: Any bits set here will be set as CLIENT SSL options */ + long ssl_client_options_clear; + /**< VHOST: Any bits set here will be cleared as CLIENT SSL options */ + + /* Add new things just above here ---^ * This is part of the ABI, don't needlessly break compatibility * diff --git a/lib/roles/http/server/lejp-conf.c b/lib/roles/http/server/lejp-conf.c index 0dfa76b92..425c956aa 100644 --- a/lib/roles/http/server/lejp-conf.c +++ b/lib/roles/http/server/lejp-conf.c @@ -105,6 +105,8 @@ static const char * const paths_vhosts[] = { "vhosts[].ignore-missing-cert", "vhosts[].error-document-404", "vhosts[].alpn", + "vhosts[].ssl-client-option-set", + "vhosts[].ssl-client-option-clear", }; enum lejp_vhost_paths { @@ -156,6 +158,8 @@ enum lejp_vhost_paths { LEJPVP_IGNORE_MISSING_CERT, LEJPVP_ERROR_DOCUMENT_404, LEJPVP_ALPN, + LEJPVP_SSL_CLIENT_OPTION_SET, + LEJPVP_SSL_CLIENT_OPTION_CLEAR, }; static const char * const parser_errs[] = { @@ -750,6 +754,13 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason) a->info->ssl_options_clear |= atol(ctx->buf); return 0; + case LEJPVP_SSL_CLIENT_OPTION_SET: + a->info->ssl_client_options_set |= atol(ctx->buf); + return 0; + case LEJPVP_SSL_CLIENT_OPTION_CLEAR: + a->info->ssl_client_options_clear |= atol(ctx->buf); + return 0; + case LEJPVP_ALPN: a->info->alpn = a->p; break; diff --git a/lib/tls/openssl/openssl-client.c b/lib/tls/openssl/openssl-client.c index 23a9ffeb2..52976d712 100644 --- a/lib/tls/openssl/openssl-client.c +++ b/lib/tls/openssl/openssl-client.c @@ -375,6 +375,17 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, SSL_CTX_set_options(vh->tls.ssl_client_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + if (info->ssl_client_options_set) + SSL_CTX_set_options(vh->tls.ssl_client_ctx, + info->ssl_client_options_set); + + /* SSL_clear_options introduced in 0.9.8m */ +#if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL) + if (info->ssl_client_options_clear) + SSL_CTX_clear_options(vh->tls.ssl_client_ctx, + info->ssl_client_options_clear); +#endif + if (cipher_list) SSL_CTX_set_cipher_list(vh->tls.ssl_client_ctx, cipher_list); diff --git a/lib/tls/tls-client.c b/lib/tls/tls-client.c index 3772aaa88..881f7c429 100644 --- a/lib/tls/tls-client.c +++ b/lib/tls/tls-client.c @@ -128,7 +128,10 @@ int lws_context_init_client_ssl(const struct lws_context_creation_info *info, } if (lws_tls_client_create_vhost_context(vhost, info, cipher_list, - ca_filepath, info->client_ssl_ca_mem, info->client_ssl_ca_mem_len, cert_filepath, + ca_filepath, + info->client_ssl_ca_mem, + info->client_ssl_ca_mem_len, + cert_filepath, private_key_filepath)) return 1;