Skip to content

Commit

Permalink
Rework TLS engine support.
Browse files Browse the repository at this point in the history
  • Loading branch information
ralight committed Feb 26, 2019
1 parent 20894fc commit e862a04
Show file tree
Hide file tree
Showing 20 changed files with 225 additions and 249 deletions.
22 changes: 11 additions & 11 deletions client/client_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void client_config_cleanup(struct mosq_config *cfg)
free(cfg->ciphers);
free(cfg->tls_version);
free(cfg->tls_engine);
free(cfg->tls_engine_kpass_sha);
free(cfg->tls_engine_kpass_sha1);
free(cfg->keyform);
# ifdef WITH_TLS_PSK
free(cfg->psk);
Expand Down Expand Up @@ -308,15 +308,15 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *
}
#ifdef WITH_TLS
if((cfg->certfile && !cfg->keyfile) || (cfg->keyfile && !cfg->certfile)){
fprintf(stderr, "Error: Both certfile and keyfile must be provided if one of them is.\n");
fprintf(stderr, "Error: Both certfile and keyfile must be provided if one of them is set.\n");
return 1;
}
if((cfg->keyform && !cfg->keyfile)){
fprintf(stderr, "Error: keyfile must be specified if keyform is.\n");
fprintf(stderr, "Error: If keyform is set, keyfile must be also specified.\n");
return 1;
}
if((cfg->tls_engine_kpass_sha && (!cfg->keyform || !cfg->tls_engine))){
fprintf(stderr, "Error: when using tls-engine-kpass-sha, both tls-engine and keyform must also be provided.\n");
if((cfg->tls_engine_kpass_sha1 && (!cfg->keyform || !cfg->tls_engine))){
fprintf(stderr, "Error: when using tls-engine-kpass-sha1, both tls-engine and keyform must also be provided.\n");
return 1;
}
#endif
Expand Down Expand Up @@ -444,12 +444,12 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
cfg->tls_engine = strdup(argv[i+1]);
}
i++;
}else if(!strcmp(argv[i], "--tls-engine-kpass-sha")){
}else if(!strcmp(argv[i], "--tls-engine-kpass-sha1")){
if(i==argc-1){
fprintf(stderr, "Error: --tls-engine-kpass-sha argument given but no kpass sha specified.\n\n");
fprintf(stderr, "Error: --tls-engine-kpass-sha1 argument given but no kpass sha1 specified.\n\n");
return 1;
}else{
cfg->tls_engine_kpass_sha = strdup(argv[i+1]);
cfg->tls_engine_kpass_sha1 = strdup(argv[i+1]);
}
i++;
#endif
Expand Down Expand Up @@ -952,17 +952,17 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
mosquitto_lib_cleanup();
return 1;
}
if(cfg->tls_engine && mosquitto_tls_engine_set(mosq, cfg->tls_engine)){
if(cfg->tls_engine && mosquitto_string_option(mosq, MOSQ_OPT_TLS_ENGINE, cfg->tls_engine)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS engine.\n");
mosquitto_lib_cleanup();
return 1;
}
if(cfg->keyform && mosquitto_tls_keyform_set(mosq, cfg->keyform)){
if(cfg->keyform && mosquitto_string_option(mosq, MOSQ_OPT_TLS_KEYFORM, cfg->keyform)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting keyform.\n");
mosquitto_lib_cleanup();
return 1;
}
if(cfg->tls_engine_kpass_sha && mosquitto_tls_engine_kpass_sha_set(mosq, cfg->tls_engine_kpass_sha)){
if(cfg->tls_engine_kpass_sha1 && mosquitto_string_option(mosq, MOSQ_OPT_TLS_ENGINE_KPASS_SHA1, cfg->tls_engine_kpass_sha1)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS engine key pass sha.\n");
mosquitto_lib_cleanup();
return 1;
Expand Down
2 changes: 1 addition & 1 deletion client/client_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct mosq_config {
bool insecure;
char *tls_version;
char *tls_engine;
char *tls_engine_kpass_sha;
char *tls_engine_kpass_sha1;
char *keyform;
# ifdef WITH_TLS_PSK
char *psk;
Expand Down
10 changes: 5 additions & 5 deletions client/pub_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ void print_usage(void)
printf(" [--will-topic [--will-payload payload] [--will-qos qos] [--will-retain]]\n");
#ifdef WITH_TLS
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
printf(" [--keyform keyform] [--tls-engine-kpass-sha]]\n");
printf(" [--ciphers ciphers] [--insecure]\n");
printf(" [--tls-engine engine] [--keyform keyform] [--tls-engine-kpass-sha1]]\n");
#ifdef WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
Expand Down Expand Up @@ -274,16 +274,16 @@ void print_usage(void)
printf(" communication.\n");
printf(" --cert : client certificate for authentication, if required by server.\n");
printf(" --key : client private key for authentication, if required by server.\n");
printf(" --keyform : keyfile type, can be one of pem or engine.\n");
printf(" --keyform : keyfile type, can be either \"pem\" or \"engine\".\n");
printf(" --ciphers : openssl compatible list of TLS ciphers to support.\n");
printf(" --tls-version : TLS protocol version, can be one of tlsv1.2 tlsv1.1 or tlsv1.\n");
printf(" Defaults to tlsv1.2 if available.\n");
printf(" --insecure : do not check that the server certificate hostname matches the remote\n");
printf(" hostname. Using this option means that you cannot be sure that the\n");
printf(" remote host is the server you wish to connect to and so is insecure.\n");
printf(" Do not use this option in a production environment.\n");
printf(" --tls-engine : toggles the usage of a SSL engine device.\n");
printf(" --tls-engine-kpass-sha : SHA1 of the key password to be used with the selected SSL engine.\n");
printf(" --tls-engine : If set, enables the use of a SSL engine device.\n");
printf(" --tls-engine-kpass-sha1 : SHA1 of the key password to be used with the selected SSL engine.\n");
# ifdef WITH_TLS_PSK
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
Expand Down
8 changes: 4 additions & 4 deletions client/sub_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void print_usage(void)
#ifdef WITH_TLS
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
printf(" [--keyform keyform] [--tls-engine-kpass-sha]]\n");
printf(" [--keyform keyform] [--tls-engine-kpass-sha1]]\n");
#ifdef WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
Expand Down Expand Up @@ -216,16 +216,16 @@ void print_usage(void)
printf(" communication.\n");
printf(" --cert : client certificate for authentication, if required by server.\n");
printf(" --key : client private key for authentication, if required by server.\n");
printf(" --keyform : keyfile type, can be one of pem or engine.\n");
printf(" --keyform : keyfile type, can be either \"pem\" or \"engine\".\n");
printf(" --ciphers : openssl compatible list of TLS ciphers to support.\n");
printf(" --tls-version : TLS protocol version, can be one of tlsv1.2 tlsv1.1 or tlsv1.\n");
printf(" Defaults to tlsv1.2 if available.\n");
printf(" --insecure : do not check that the server certificate hostname matches the remote\n");
printf(" hostname. Using this option means that you cannot be sure that the\n");
printf(" remote host is the server you wish to connect to and so is insecure.\n");
printf(" Do not use this option in a production environment.\n");
printf(" --tls-engine : toggles the usage of a SSL engine device.\n");
printf(" --tls-engine-kpass-sha : SHA1 of the key password to be used with the selected SSL engine.\n");
printf(" --tls-engine : If set, enables the use of a SSL engine device.\n");
printf(" --tls-engine-kpass-sha1 : SHA1 of the key password to be used with the selected SSL engine.\n");
#ifdef WITH_TLS_PSK
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
Expand Down
2 changes: 2 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#define _GNU_SOURCE

#define OPENSSL_LOAD_CONF

/* ============================================================
* Compatibility defines
* ============================================================ */
Expand Down
15 changes: 0 additions & 15 deletions lib/cpp/mosquittopp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,19 +366,4 @@ int mosquittopp::tls_psk_set(const char *psk, const char *identity, const char *
return mosquitto_tls_psk_set(m_mosq, psk, identity, ciphers);
}

int mosquittopp::tls_engine_set(const char *engine_id)
{
return mosquitto_tls_engine_set(m_mosq, engine_id);
}

int mosquittopp::tls_keyform_set(const char *keyform)
{
return mosquitto_tls_keyform_set(m_mosq, keyform);
}

int mosquittopp::tls_engine_kpass_sha_set(const char *kpass_sha)
{
return mosquitto_tls_engine_kpass_sha_set(m_mosq, kpass_sha);
}

}
3 changes: 0 additions & 3 deletions lib/cpp/mosquittopp.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ class mosqpp_EXPORT mosquittopp {
int tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL);
int tls_insecure_set(bool value);
int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
int tls_engine_set(const char *engine_id);
int tls_keyform_set(const char *keyform);
int tls_engine_kpass_sha_set(const char *kpass_sha);
int opts_set(enum mosq_opt_t option, void *value);

int loop(int timeout=-1, int max_packets=1);
Expand Down
4 changes: 1 addition & 3 deletions lib/linker.version
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,10 @@ MOSQ_1.5 {
mosquitto_sub_topic_check2;
mosquitto_topic_matches_sub2;
mosquitto_connect_with_flags_callback_set;
mosquitto_tls_engine_set;
mosquitto_tls_keyform_set;
mosquitto_tls_engine_kpass_sha_set;
} MOSQ_1.4;

MOSQ_1.6 {
global:
mosquitto_string_option;
mosquitto_subscribe_multiple;
} MOSQ_1.5;
95 changes: 36 additions & 59 deletions lib/mosquitto.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,13 @@ enum mosq_opt_t {
MOSQ_OPT_PROTOCOL_VERSION = 1,
MOSQ_OPT_SSL_CTX = 2,
MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3,

MOSQ_OPT_TLS_KEYFORM = 6,
MOSQ_OPT_TLS_ENGINE = 7,
MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8,
};


/* MQTT specification restricts client ids to a maximum of 23 characters */
#define MOSQ_MQTT_ID_MAX_LENGTH 23

Expand Down Expand Up @@ -1160,65 +1165,6 @@ libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs,
*/
libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers);

/*
* Function: mosquitto_tls_engine_set
*
* Configure the client for TLS engine support. Must be called
* before <mosquitto_connect>.
*
* Parameters:
* mosq - a valid mosquitto instance.
* engine_id - the engine ID that wants to be used.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success.
* MOSQ_ERR_INVAL - if the input parameters were invalid.
*
* See Also:
* <mosquitto_tls_set>
*/
libmosq_EXPORT int mosquitto_tls_engine_set(struct mosquitto *mosq, const char *engine_id);

/*
* Function: mosquitto_tls_keyform_set
*
* Configure the client to treat the keyfile differently depending on its type.
* Must be called before <mosquitto_connect>.
*
* Parameters:
* mosq - a valid mosquitto instance.
* keyform - the key type. Currently only "pem" or "engine" are supported.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success.
* MOSQ_ERR_INVAL - if the input parameters were invalid.
*
* See Also:
* <mosquitto_tls_set>
*/
libmosq_EXPORT int mosquitto_tls_keyform_set(struct mosquitto *mosq, const char *keyform);

/*
* Function: mosquitto_tls_engine_kpass_sha_set
*
* Some SSL engines may require the usage of a password in order to being
* accessed, like the TPM engine. This function allows a SHA1 hash of the
* password to be passed on to the engine directly.
* Must be called before <mosquitto_connect>.
*
* Parameters:
* mosq - a valid mosquitto instance.
* kpass_sha - SHA1 of the private key password.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success.
* MOSQ_ERR_INVAL - if the input parameters were invalid.
*
* See Also:
* <mosquitto_tls_set>
*/
libmosq_EXPORT int mosquitto_tls_engine_kpass_sha_set(struct mosquitto *mosq, const char *kpass_sha);

/*
* Function: mosquitto_connect_callback_set
*
Expand Down Expand Up @@ -1391,6 +1337,37 @@ libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, v
*/
libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *));


/*
* Function: mosquitto_string_option
*
* Used to set const char* options for the client.
*
* Parameters:
* mosq - a valid mosquitto instance.
* option - the option to set.
* value - the option specific value.
*
* Options:
* MOSQ_OPT_TLS_ENGINE
* Configure the client for TLS Engine support. Pass a TLS Engine ID
* to be used when creating TLS connections.
* Must be set before <mosquitto_connect>.
* MOSQ_OPT_TLS_KEYFORM
* Configure the client to treat the keyfile differently depending
* on its type. Must be set before <mosquitto_connect>.
* Set as either "pem" or "engine", to determine from where the
* private key for a TLS connection will be obtained. Defaults to
* "pem", a normal private key file.
* MOSQ_OPT_TLS_KPASS_SHA1
* Where the TLS Engine requires the use of a password to be
* accessed, this option allows a hex encoded SHA1 hash of the
* private key password to be passed to the engine directly.
* Must be set before <mosquitto_connect>.
*/
libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value);


/*
* Function: mosquitto_reconnect_delay_set
*
Expand Down
6 changes: 3 additions & 3 deletions lib/mosquitto_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ struct mosquitto_message_all{
};

#ifdef WITH_TLS
enum _mosquitto_keyform {
enum mosquitto__keyform {
mosq_k_pem = 0,
mosq_k_engine = 1,
};
Expand Down Expand Up @@ -199,8 +199,8 @@ struct mosquitto {
bool tls_insecure;
bool ssl_ctx_defaults;
char *tls_engine;
char *tls_engine_kpass_sha;
enum _mosquitto_keyform tls_keyform;
char *tls_engine_kpass_sha1;
enum mosquitto__keyform tls_keyform;
#endif
bool want_write;
bool want_connect;
Expand Down
7 changes: 3 additions & 4 deletions lib/net_mosq.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ int net__init(void)
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
OPENSSL_config(NULL);
ENGINE_load_builtin_engines();
setup_ui_method();
if(tls_ex_index_mosq == -1){
Expand Down Expand Up @@ -616,15 +615,15 @@ static int net__init_ssl_ctx(struct mosquitto *mosq)
if(mosq->tls_keyfile){
if(mosq->tls_keyform == mosq_k_engine){
UI_METHOD *ui_method = net__get_ui_method();
if(mosq->tls_engine_kpass_sha){
if(mosq->tls_engine_kpass_sha1){
if(!ENGINE_ctrl_cmd(engine, ENGINE_SECRET_MODE, ENGINE_SECRET_MODE_SHA, NULL, NULL, 0)){
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set engine secret mode sha");
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set engine secret mode sha1");
ENGINE_FINISH(engine);
COMPAT_CLOSE(mosq->sock);
net__print_ssl_error(mosq);
return MOSQ_ERR_TLS;
}
if(!ENGINE_ctrl_cmd(engine, ENGINE_PIN, 0, mosq->tls_engine_kpass_sha, NULL, 0)){
if(!ENGINE_ctrl_cmd(engine, ENGINE_PIN, 0, mosq->tls_engine_kpass_sha1, NULL, 0)){
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set engine pin");
ENGINE_FINISH(engine);
COMPAT_CLOSE(mosq->sock);
Expand Down
Loading

0 comments on commit e862a04

Please sign in to comment.