Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Openssl engine support - revisited #915

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add TLS engine and keyform support to mosquitto
Add same OpenSSL engine support to mosquitto (server side) previously added to
client side only.

Signed-off-by: Nicolás Pernas Maradei <[email protected]>
  • Loading branch information
nicopernas committed Aug 11, 2018
commit c311757b5741564757d208e0850c8ba9aeb27724
16 changes: 16 additions & 0 deletions man/mosquitto.conf.5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,22 @@
the "openssl ciphers" command.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>tls_engine</option> <replaceable>engine</replaceable></term>
<listitem>
<para>A valid openssl engine id. These can be listed with
openssl engine command.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>tls_keyform</option> [ pem | engine ]</term>
<listitem>
<para>Specifies the type of key in use. This could be pem or
engine. This parameter is useful for example when a TPM
module is being used and the key has been created with
it. If not specified, pem keys are assumed</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>crlfile</option> <replaceable>file path</replaceable></term>
<listitem>
Expand Down
23 changes: 23 additions & 0 deletions src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ void config__cleanup(struct mosquitto__config *config)
mosquitto__free(config->listeners[i].psk_hint);
mosquitto__free(config->listeners[i].crlfile);
mosquitto__free(config->listeners[i].tls_version);
mosquitto__free(config->listeners[i].tls_engine);
#ifdef WITH_WEBSOCKETS
if(!config->listeners[i].ws_context) /* libwebsockets frees its own SSL_CTX */
#endif
Expand Down Expand Up @@ -433,6 +434,8 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
|| config->default_listener.capath
|| config->default_listener.certfile
|| config->default_listener.keyfile
|| config->default_listener.tls_engine
|| config->default_listener.tls_keyform != mosq_k_pem
|| config->default_listener.ciphers
|| config->default_listener.psk_hint
|| config->default_listener.require_certificate
Expand Down Expand Up @@ -483,6 +486,8 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
config->listeners[config->listener_count-1].use_username_as_clientid = config->default_listener.use_username_as_clientid;
#ifdef WITH_TLS
config->listeners[config->listener_count-1].tls_version = config->default_listener.tls_version;
config->listeners[config->listener_count-1].tls_engine = config->default_listener.tls_engine;
config->listeners[config->listener_count-1].tls_keyform = config->default_listener.tls_keyform;
config->listeners[config->listener_count-1].cafile = config->default_listener.cafile;
config->listeners[config->listener_count-1].capath = config->default_listener.capath;
config->listeners[config->listener_count-1].certfile = config->default_listener.certfile;
Expand Down Expand Up @@ -1076,6 +1081,24 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
if(conf__parse_string(&token, "certfile", &cur_listener->certfile, saveptr)) return MOSQ_ERR_INVAL;
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available.");
#endif
}else if(!strcmp(token, "tls_engine")){
#ifdef WITH_TLS
if(reload) continue; // Listeners not valid for reloading.
if(conf__parse_string(&token, "tls_engine", &cur_listener->tls_engine, saveptr)) return MOSQ_ERR_INVAL;
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available.");
#endif
}else if(!strcmp(token, "tls_keyform")){
#ifdef WITH_TLS
if(reload) continue; // Listeners not valid for reloading.
char *keyform = NULL;
if(conf__parse_string(&token, "tls_keyform", &keyform, saveptr)) return MOSQ_ERR_INVAL;
cur_listener->tls_keyform = mosq_k_pem;
if(!strcmp(keyform, "engine")) cur_listener->tls_keyform = mosq_k_engine;
mosquitto__free(keyform);
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available.");
#endif
}else if(!strcmp(token, "ciphers")){
#ifdef WITH_TLS
Expand Down
2 changes: 2 additions & 0 deletions src/mosquitto_broker_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ struct mosquitto__listener {
char *capath;
char *certfile;
char *keyfile;
char *tls_engine;
enum _mosquitto_keyform tls_keyform;
char *ciphers;
char *psk_hint;
SSL_CTX *ssl_ctx;
Expand Down
50 changes: 45 additions & 5 deletions src/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ int net__socket_listen(struct mosquitto__listener *listener)
int rc;
X509_STORE *store;
X509_LOOKUP *lookup;
ENGINE *engine = NULL;
#endif

if(!listener) return MOSQ_ERR_INVAL;
Expand Down Expand Up @@ -430,6 +431,22 @@ int net__socket_listen(struct mosquitto__listener *listener)
COMPAT_CLOSE(sock);
return 1;
}
if(listener->tls_engine){
engine = ENGINE_by_id(listener->tls_engine);
if(!engine){
log__printf(NULL, MOSQ_LOG_ERR, "Error loading %s engine\n", listener->tls_engine);
COMPAT_CLOSE(sock);
return 1;
}
if(!ENGINE_init(engine)){
log__printf(NULL, MOSQ_LOG_ERR, "Failed engine initialisation\n");
ENGINE_free(engine);
COMPAT_CLOSE(sock);
return 1;
}
ENGINE_set_default(engine, ENGINE_METHOD_ALL);
ENGINE_free(engine); /* release the structural reference from ENGINE_by_id() */
}
/* FIXME user data? */
if(listener->require_certificate){
SSL_CTX_set_verify(listener->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, client_certificate_verify);
Expand All @@ -440,18 +457,37 @@ int net__socket_listen(struct mosquitto__listener *listener)
if(rc != 1){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server certificate \"%s\". Check certfile.", listener->certfile);
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
rc = SSL_CTX_use_PrivateKey_file(listener->ssl_ctx, listener->keyfile, SSL_FILETYPE_PEM);
if(rc != 1){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server key file \"%s\". Check keyfile.", listener->keyfile);
COMPAT_CLOSE(sock);
return 1;
if(listener->tls_keyform == mosq_k_engine){
EVP_PKEY *pkey = ENGINE_load_private_key(engine, listener->keyfile, net__get_ui_method(), NULL);
if(!pkey){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load engine private key file \"%s\".", listener->keyfile);
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
if(SSL_CTX_use_PrivateKey(listener->ssl_ctx, pkey) <= 0){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to use engine private key file \"%s\".", listener->keyfile);
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
}else{
rc = SSL_CTX_use_PrivateKey_file(listener->ssl_ctx, listener->keyfile, SSL_FILETYPE_PEM);
if(rc != 1){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server key file \"%s\". Check keyfile.", listener->keyfile);
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
}
rc = SSL_CTX_check_private_key(listener->ssl_ctx);
if(rc != 1){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Server certificate/key are inconsistent.");
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
/* Load CRLs if they exist. */
Expand All @@ -460,13 +496,15 @@ int net__socket_listen(struct mosquitto__listener *listener)
if(!store){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to obtain TLS store.");
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
rc = X509_load_crl_file(lookup, listener->crlfile, X509_FILETYPE_PEM);
if(rc != 1){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load certificate revocation file \"%s\". Check crlfile.", listener->crlfile);
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK);
Expand All @@ -483,6 +521,7 @@ int net__socket_listen(struct mosquitto__listener *listener)

if(mosquitto__tls_server_ctx(listener)){
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
SSL_CTX_set_psk_server_callback(listener->ssl_ctx, psk_server_callback);
Expand All @@ -491,6 +530,7 @@ int net__socket_listen(struct mosquitto__listener *listener)
if(rc == 0){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS PSK hint.");
COMPAT_CLOSE(sock);
ENGINE_FINISH(engine);
return 1;
}
}
Expand Down