Add dhparamfile option, to allow DH parameters to be loaded.

This is for Ephemeral DH support on listeners.
This commit is contained in:
Roger A. Light 2019-02-27 22:26:40 +00:00
parent 1a3eaeabce
commit 130ddf47f7
6 changed files with 53 additions and 1 deletions

View File

@ -12,6 +12,8 @@ Broker features:
specific network interface, in a similar fashion to the `bind_address` option. specific network interface, in a similar fashion to the `bind_address` option.
Linux only. Linux only.
- Add improved bridge restart interval based on Decorrelated Jitter. - Add improved bridge restart interval based on Decorrelated Jitter.
- Add `dhparamfile` option, to allow DH parameters to be loaded for Ephemeral
DH support
Client library features: Client library features:
- Add mosquitto_subscribe_multiple() for sending subscriptions to multiple - Add mosquitto_subscribe_multiple() for sending subscriptions to multiple

View File

@ -1041,6 +1041,18 @@
encoded revocation file.</para> encoded revocation file.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>dhparamfile</option> <replaceable>file path</replaceable></term>
<listitem>
<para>To allow the use of ephemeral DH key exchange,
which provides forward security, the listener must
load DH parameters. This can be specified with the
dhparamfile option. The dhparamfile can be
generated with the command e.g.</para>
<programlisting>
openssl dhparam -out dhparam.pem 2048</programlisting>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>keyfile</option> <replaceable>file path</replaceable></term> <term><option>keyfile</option> <replaceable>file path</replaceable></term>
<listitem> <listitem>

View File

@ -312,6 +312,12 @@
# If unset defaults to DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH # If unset defaults to DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH
#ciphers DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH #ciphers DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH
# To allow the use of ephemeral DH key exchange, which provides forward
# security, the listener must load DH parameters. This can be specified with
# the dhparamfile option. The dhparamfile can be generated with the command
# e.g. "openssl dhparam -out dhparam.pem 2048"
#dhparamfile
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# Pre-shared-key based SSL/TLS support # Pre-shared-key based SSL/TLS support
# ----------------------------------------------------------------- # -----------------------------------------------------------------
@ -463,6 +469,12 @@
# that command. # that command.
#ciphers #ciphers
# To allow the use of ephemeral DH key exchange, which provides forward
# security, the listener must load DH parameters. This can be specified with
# the dhparamfile option. The dhparamfile can be generated with the command
# e.g. "openssl dhparam -out dhparam.pem 2048"
#dhparamfile
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# Pre-shared-key based SSL/TLS support # Pre-shared-key based SSL/TLS support
# ----------------------------------------------------------------- # -----------------------------------------------------------------

View File

@ -306,6 +306,7 @@ void config__cleanup(struct mosquitto__config *config)
mosquitto__free(config->listeners[i].ciphers); mosquitto__free(config->listeners[i].ciphers);
mosquitto__free(config->listeners[i].psk_hint); mosquitto__free(config->listeners[i].psk_hint);
mosquitto__free(config->listeners[i].crlfile); mosquitto__free(config->listeners[i].crlfile);
mosquitto__free(config->listeners[i].dhparamfile);
mosquitto__free(config->listeners[i].tls_version); mosquitto__free(config->listeners[i].tls_version);
mosquitto__free(config->listeners[i].tls_engine); mosquitto__free(config->listeners[i].tls_engine);
mosquitto__free(config->listeners[i].tls_engine_kpass_sha1); mosquitto__free(config->listeners[i].tls_engine_kpass_sha1);
@ -448,6 +449,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
|| config->default_listener.tls_keyform != mosq_k_pem || config->default_listener.tls_keyform != mosq_k_pem
|| config->default_listener.tls_engine_kpass_sha1 || config->default_listener.tls_engine_kpass_sha1
|| config->default_listener.ciphers || config->default_listener.ciphers
|| config->default_listener.dhparamfile
|| config->default_listener.psk_hint || config->default_listener.psk_hint
|| config->default_listener.require_certificate || config->default_listener.require_certificate
|| config->default_listener.crlfile || config->default_listener.crlfile
@ -509,6 +511,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
config->listeners[config->listener_count-1].certfile = config->default_listener.certfile; config->listeners[config->listener_count-1].certfile = config->default_listener.certfile;
config->listeners[config->listener_count-1].keyfile = config->default_listener.keyfile; config->listeners[config->listener_count-1].keyfile = config->default_listener.keyfile;
config->listeners[config->listener_count-1].ciphers = config->default_listener.ciphers; config->listeners[config->listener_count-1].ciphers = config->default_listener.ciphers;
config->listeners[config->listener_count-1].dhparamfile = config->default_listener.dhparamfile;
config->listeners[config->listener_count-1].psk_hint = config->default_listener.psk_hint; config->listeners[config->listener_count-1].psk_hint = config->default_listener.psk_hint;
config->listeners[config->listener_count-1].require_certificate = config->default_listener.require_certificate; config->listeners[config->listener_count-1].require_certificate = config->default_listener.require_certificate;
config->listeners[config->listener_count-1].ssl_ctx = NULL; config->listeners[config->listener_count-1].ssl_ctx = NULL;
@ -1203,6 +1206,13 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
if(conf__parse_string(&token, "crlfile", &cur_listener->crlfile, saveptr)) return MOSQ_ERR_INVAL; if(conf__parse_string(&token, "crlfile", &cur_listener->crlfile, saveptr)) return MOSQ_ERR_INVAL;
#else #else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available.");
#endif
}else if(!strcmp(token, "dhparamfile")){
#ifdef WITH_TLS
if(reload) continue; // Listeners not valid for reloading.
if(conf__parse_string(&token, "dhparamfile", &cur_listener->dhparamfile, saveptr)) return MOSQ_ERR_INVAL;
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available.");
#endif #endif
}else if(!strcmp(token, "http_dir")){ }else if(!strcmp(token, "http_dir")){
#ifdef WITH_WEBSOCKETS #ifdef WITH_WEBSOCKETS

View File

@ -234,6 +234,7 @@ struct mosquitto__listener {
SSL_CTX *ssl_ctx; SSL_CTX *ssl_ctx;
char *crlfile; char *crlfile;
char *tls_version; char *tls_version;
char *dhparamfile;
bool use_identity_as_username; bool use_identity_as_username;
bool use_subject_as_username; bool use_subject_as_username;
bool require_certificate; bool require_certificate;

View File

@ -312,7 +312,8 @@ static int mosquitto__tls_server_ctx(struct mosquitto__listener *listener)
{ {
char buf[256]; char buf[256];
int rc; int rc;
FILE *dhparamfile;
DH *dhparam = NULL;
#if OPENSSL_VERSION_NUMBER < 0x10100000L #if OPENSSL_VERSION_NUMBER < 0x10100000L
listener->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); listener->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
@ -371,6 +372,20 @@ static int mosquitto__tls_server_ctx(struct mosquitto__listener *listener)
return 1; return 1;
} }
} }
if(listener->dhparamfile){
dhparamfile = fopen(listener->dhparamfile, "r");
if(!dhparamfile){
log__printf(NULL, MOSQ_LOG_ERR, "Error loading dhparamfile \"%s\".", listener->dhparamfile);
return 1;
}
dhparam = PEM_read_DHparams(dhparamfile, NULL, NULL, NULL);
fclose(dhparamfile);
if(dhparam == NULL || SSL_CTX_set_tmp_dh(listener->ssl_ctx, dhparam) != 1){
log__printf(NULL, MOSQ_LOG_ERR, "Error loading dhparamfile \"%s\".", listener->dhparamfile);
return 1;
}
}
return MOSQ_ERR_SUCCESS; return MOSQ_ERR_SUCCESS;
} }
#endif #endif