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 all commits
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
50 changes: 50 additions & 0 deletions client/client_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ void client_config_cleanup(struct mosq_config *cfg)
free(cfg->keyfile);
free(cfg->ciphers);
free(cfg->tls_version);
free(cfg->tls_engine);
free(cfg->tls_engine_kpass_sha);
free(cfg->keyform);
# ifdef WITH_TLS_PSK
free(cfg->psk);
free(cfg->psk_identity);
Expand Down Expand Up @@ -308,6 +311,14 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *
fprintf(stderr, "Error: Both certfile and keyfile must be provided if one of them is.\n");
return 1;
}
if((cfg->keyform && !cfg->keyfile)){
fprintf(stderr, "Error: keyfile must be specified if keyform is.\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");
return 1;
}
#endif
#ifdef WITH_TLS_PSK
if((cfg->cafile || cfg->capath) && cfg->psk){
Expand Down Expand Up @@ -425,6 +436,22 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
cfg->ciphers = strdup(argv[i+1]);
}
i++;
}else if(!strcmp(argv[i], "--tls-engine")){
if(i==argc-1){
fprintf(stderr, "Error: --tls-engine argument given but no engine_id specified.\n\n");
return 1;
}else{
cfg->tls_engine = strdup(argv[i+1]);
}
i++;
}else if(!strcmp(argv[i], "--tls-engine-kpass-sha")){
if(i==argc-1){
fprintf(stderr, "Error: --tls-engine-kpass-sha argument given but no kpass sha specified.\n\n");
return 1;
}else{
cfg->tls_engine_kpass_sha = strdup(argv[i+1]);
}
i++;
#endif
}else if(!strcmp(argv[i], "-C")){
if(pub_or_sub == CLIENT_PUB){
Expand Down Expand Up @@ -556,6 +583,14 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
cfg->keyfile = strdup(argv[i+1]);
}
i++;
}else if(!strcmp(argv[i], "--keyform")){
if(i==argc-1){
fprintf(stderr, "Error: --keyform argument given but no keyform specified.\n\n");
return 1;
}else{
cfg->keyform = strdup(argv[i+1]);
}
i++;
#endif
}else if(!strcmp(argv[i], "-L") || !strcmp(argv[i], "--url")){
if(i==argc-1){
Expand Down Expand Up @@ -912,6 +947,21 @@ 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->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->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->quiet) fprintf(stderr, "Error: Problem setting TLS engine key pass sha.\n");
mosquitto_lib_cleanup();
return 1;
}
# ifdef WITH_TLS_PSK
if(cfg->psk && mosquitto_tls_psk_set(mosq, cfg->psk, cfg->psk_identity, NULL)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS-PSK options.\n");
Expand Down
3 changes: 3 additions & 0 deletions client/client_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ struct mosq_config {
char *ciphers;
bool insecure;
char *tls_version;
char *tls_engine;
char *tls_engine_kpass_sha;
char *keyform;
# ifdef WITH_TLS_PSK
char *psk;
char *psk_identity;
Expand Down
6 changes: 5 additions & 1 deletion client/pub_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,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]]\n");
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
printf(" [--keyform keyform] [--tls-engine-kpass-sha]]\n");
#ifdef WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
Expand Down Expand Up @@ -274,13 +275,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(" --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");
# 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
6 changes: 5 additions & 1 deletion client/sub_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,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]]\n");
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
printf(" [--keyform keyform] [--tls-engine-kpass-sha]]\n");
#ifdef WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
Expand Down Expand Up @@ -211,13 +212,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(" --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");
#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
15 changes: 15 additions & 0 deletions lib/cpp/mosquittopp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,19 @@ 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: 3 additions & 0 deletions lib/cpp/mosquittopp.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ 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
3 changes: 3 additions & 0 deletions lib/linker.version
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,7 @@ 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;
59 changes: 59 additions & 0 deletions lib/mosquitto.h
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,65 @@ 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
10 changes: 10 additions & 0 deletions lib/mosquitto_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ struct mosquitto_message_all{
struct mosquitto_message msg;
};

#ifdef WITH_TLS
enum _mosquitto_keyform {
mosq_k_pem = 0,
mosq_k_engine = 1,
};
#endif

struct mosquitto {
mosq_sock_t sock;
#ifndef WITH_BROKER
Expand Down Expand Up @@ -189,6 +196,9 @@ struct mosquitto {
int tls_cert_reqs;
bool tls_insecure;
bool ssl_ctx_defaults;
char *tls_engine;
char *tls_engine_kpass_sha;
enum _mosquitto_keyform tls_keyform;
#endif
bool want_write;
bool want_connect;
Expand Down
Loading