Add engine private key password support
Some OpenSSL engines (selectable via tls_engine option) may require a password to make use of private keys created with them in the first place. The TPM engine for example, will require a password to access the underlying TPM's Storage Root Key (SRK), which is the root key of a hierarchy of keys associated with a TPM; it is generated within a TPM and is a non-migratable key. Each owned TPM contains a SRK, generated by the TPM at the request of the Owner. [1] By default, the engine will prompt the user to introduce the SRK password before any private keys created with the engine can be used. This could be inconvenient when running on an unattended system. Here's where the new tls_engine_kpass_sha option comes in handy. The user can specify a SHA1 hash of its engine private key password via command line or config file and it will be passed on to the engine directly. This commit adds support for both clients (libmosquitto) and broker. [1] https://goo.gl/qQoXBY Signed-off-by: Nicolás Pernas Maradei <nicopernas@gmail.com>
This commit is contained in:
parent
d5f039ec7c
commit
20894fcbce
@ -152,6 +152,7 @@ void client_config_cleanup(struct mosq_config *cfg)
|
|||||||
free(cfg->ciphers);
|
free(cfg->ciphers);
|
||||||
free(cfg->tls_version);
|
free(cfg->tls_version);
|
||||||
free(cfg->tls_engine);
|
free(cfg->tls_engine);
|
||||||
|
free(cfg->tls_engine_kpass_sha);
|
||||||
free(cfg->keyform);
|
free(cfg->keyform);
|
||||||
# ifdef WITH_TLS_PSK
|
# ifdef WITH_TLS_PSK
|
||||||
free(cfg->psk);
|
free(cfg->psk);
|
||||||
@ -314,6 +315,10 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *
|
|||||||
fprintf(stderr, "Error: keyfile must be specified if keyform is.\n");
|
fprintf(stderr, "Error: keyfile must be specified if keyform is.\n");
|
||||||
return 1;
|
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
|
#endif
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS_PSK
|
||||||
if((cfg->cafile || cfg->capath) && cfg->psk){
|
if((cfg->cafile || cfg->capath) && cfg->psk){
|
||||||
@ -439,6 +444,14 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
|
|||||||
cfg->tls_engine = strdup(argv[i+1]);
|
cfg->tls_engine = strdup(argv[i+1]);
|
||||||
}
|
}
|
||||||
i++;
|
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
|
#endif
|
||||||
}else if(!strcmp(argv[i], "-C")){
|
}else if(!strcmp(argv[i], "-C")){
|
||||||
if(pub_or_sub == CLIENT_PUB){
|
if(pub_or_sub == CLIENT_PUB){
|
||||||
@ -949,6 +962,11 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
|
|||||||
mosquitto_lib_cleanup();
|
mosquitto_lib_cleanup();
|
||||||
return 1;
|
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
|
# ifdef WITH_TLS_PSK
|
||||||
if(cfg->psk && mosquitto_tls_psk_set(mosq, cfg->psk, cfg->psk_identity, NULL)){
|
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");
|
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS-PSK options.\n");
|
||||||
|
@ -67,6 +67,7 @@ struct mosq_config {
|
|||||||
bool insecure;
|
bool insecure;
|
||||||
char *tls_version;
|
char *tls_version;
|
||||||
char *tls_engine;
|
char *tls_engine;
|
||||||
|
char *tls_engine_kpass_sha;
|
||||||
char *keyform;
|
char *keyform;
|
||||||
# ifdef WITH_TLS_PSK
|
# ifdef WITH_TLS_PSK
|
||||||
char *psk;
|
char *psk;
|
||||||
|
@ -223,7 +223,7 @@ void print_usage(void)
|
|||||||
#ifdef WITH_TLS
|
#ifdef WITH_TLS
|
||||||
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
|
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
|
||||||
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
|
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
|
||||||
printf(" [--keyform keyform]]\n");
|
printf(" [--keyform keyform] [--tls-engine-kpass-sha]]\n");
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS_PSK
|
||||||
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
||||||
#endif
|
#endif
|
||||||
@ -283,6 +283,7 @@ void print_usage(void)
|
|||||||
printf(" remote host is the server you wish to connect to and so is insecure.\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(" 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 : 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
|
# ifdef WITH_TLS_PSK
|
||||||
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
|
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");
|
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
|
||||||
|
@ -158,7 +158,7 @@ void print_usage(void)
|
|||||||
#ifdef WITH_TLS
|
#ifdef WITH_TLS
|
||||||
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
|
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
|
||||||
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
|
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
|
||||||
printf(" [--keyform keyform]]\n");
|
printf(" [--keyform keyform] [--tls-engine-kpass-sha]]\n");
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS_PSK
|
||||||
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
||||||
#endif
|
#endif
|
||||||
@ -225,6 +225,7 @@ void print_usage(void)
|
|||||||
printf(" remote host is the server you wish to connect to and so is insecure.\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(" 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 : 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
|
#ifdef WITH_TLS_PSK
|
||||||
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
|
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");
|
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
|
||||||
|
@ -376,4 +376,9 @@ int mosquittopp::tls_keyform_set(const char *keyform)
|
|||||||
return mosquitto_tls_keyform_set(m_mosq, 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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ class mosqpp_EXPORT mosquittopp {
|
|||||||
int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
|
int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
|
||||||
int tls_engine_set(const char *engine_id);
|
int tls_engine_set(const char *engine_id);
|
||||||
int tls_keyform_set(const char *keyform);
|
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 opts_set(enum mosq_opt_t option, void *value);
|
||||||
|
|
||||||
int loop(int timeout=-1, int max_packets=1);
|
int loop(int timeout=-1, int max_packets=1);
|
||||||
|
@ -92,6 +92,7 @@ MOSQ_1.5 {
|
|||||||
mosquitto_connect_with_flags_callback_set;
|
mosquitto_connect_with_flags_callback_set;
|
||||||
mosquitto_tls_engine_set;
|
mosquitto_tls_engine_set;
|
||||||
mosquitto_tls_keyform_set;
|
mosquitto_tls_keyform_set;
|
||||||
|
mosquitto_tls_engine_kpass_sha_set;
|
||||||
} MOSQ_1.4;
|
} MOSQ_1.4;
|
||||||
|
|
||||||
MOSQ_1.6 {
|
MOSQ_1.6 {
|
||||||
|
@ -1198,6 +1198,27 @@ libmosq_EXPORT int mosquitto_tls_engine_set(struct mosquitto *mosq, const char *
|
|||||||
*/
|
*/
|
||||||
libmosq_EXPORT int mosquitto_tls_keyform_set(struct mosquitto *mosq, const char *keyform);
|
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
|
* Function: mosquitto_connect_callback_set
|
||||||
*
|
*
|
||||||
|
@ -199,6 +199,7 @@ struct mosquitto {
|
|||||||
bool tls_insecure;
|
bool tls_insecure;
|
||||||
bool ssl_ctx_defaults;
|
bool ssl_ctx_defaults;
|
||||||
char *tls_engine;
|
char *tls_engine;
|
||||||
|
char *tls_engine_kpass_sha;
|
||||||
enum _mosquitto_keyform tls_keyform;
|
enum _mosquitto_keyform tls_keyform;
|
||||||
#endif
|
#endif
|
||||||
bool want_write;
|
bool want_write;
|
||||||
|
@ -615,6 +615,24 @@ static int net__init_ssl_ctx(struct mosquitto *mosq)
|
|||||||
}
|
}
|
||||||
if(mosq->tls_keyfile){
|
if(mosq->tls_keyfile){
|
||||||
if(mosq->tls_keyform == mosq_k_engine){
|
if(mosq->tls_keyform == mosq_k_engine){
|
||||||
|
UI_METHOD *ui_method = net__get_ui_method();
|
||||||
|
if(mosq->tls_engine_kpass_sha){
|
||||||
|
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");
|
||||||
|
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)){
|
||||||
|
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set engine pin");
|
||||||
|
ENGINE_FINISH(engine);
|
||||||
|
COMPAT_CLOSE(mosq->sock);
|
||||||
|
net__print_ssl_error(mosq);
|
||||||
|
return MOSQ_ERR_TLS;
|
||||||
|
}
|
||||||
|
ui_method = NULL;
|
||||||
|
}
|
||||||
EVP_PKEY *pkey = ENGINE_load_private_key(engine, mosq->tls_keyfile, ui_method, NULL);
|
EVP_PKEY *pkey = ENGINE_load_private_key(engine, mosq->tls_keyfile, ui_method, NULL);
|
||||||
if(!pkey){
|
if(!pkey){
|
||||||
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load engine private key file \"%s\".", mosq->tls_keyfile);
|
log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load engine private key file \"%s\".", mosq->tls_keyfile);
|
||||||
|
@ -73,6 +73,9 @@ int net__socket_apply_tls(struct mosquitto *mosq);
|
|||||||
int net__socket_connect_tls(struct mosquitto *mosq);
|
int net__socket_connect_tls(struct mosquitto *mosq);
|
||||||
UI_METHOD *net__get_ui_method(void);
|
UI_METHOD *net__get_ui_method(void);
|
||||||
#define ENGINE_FINISH(e) if(e) ENGINE_finish(e)
|
#define ENGINE_FINISH(e) if(e) ENGINE_finish(e)
|
||||||
|
#define ENGINE_SECRET_MODE "SECRET_MODE"
|
||||||
|
#define ENGINE_SECRET_MODE_SHA 0x1000
|
||||||
|
#define ENGINE_PIN "PIN"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -257,6 +257,20 @@ int mosquitto_tls_keyform_set(struct mosquitto *mosq, const char *keyform)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mosquitto_tls_engine_kpass_sha_set(struct mosquitto *mosq, const char *kpass_sha)
|
||||||
|
{
|
||||||
|
#ifdef WITH_TLS
|
||||||
|
if(!mosq) return MOSQ_ERR_INVAL;
|
||||||
|
char *kpass_sha_bin = NULL;
|
||||||
|
if(mosquitto__hex2bin_sha1(kpass_sha, (unsigned char**)&kpass_sha_bin) != MOSQ_ERR_SUCCESS) return MOSQ_ERR_INVAL;
|
||||||
|
mosq->tls_engine_kpass_sha = kpass_sha_bin;
|
||||||
|
return MOSQ_ERR_SUCCESS;
|
||||||
|
#else
|
||||||
|
return MOSQ_ERR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers)
|
int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers)
|
||||||
{
|
{
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS_PSK
|
||||||
|
@ -346,7 +346,22 @@ int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *top
|
|||||||
return MOSQ_ERR_SUCCESS;
|
return MOSQ_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS
|
||||||
|
int mosquitto__hex2bin_sha1(const char *hex, unsigned char **bin)
|
||||||
|
{
|
||||||
|
unsigned char *sha, tmp[SHA_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
if(mosquitto__hex2bin(hex, tmp, SHA_DIGEST_LENGTH) != SHA_DIGEST_LENGTH)
|
||||||
|
return MOSQ_ERR_INVAL;
|
||||||
|
|
||||||
|
sha = mosquitto__malloc(SHA_DIGEST_LENGTH);
|
||||||
|
memcpy(sha, tmp, SHA_DIGEST_LENGTH);
|
||||||
|
*bin = sha;
|
||||||
|
return MOSQ_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WITH_TLS_PSK) || defined(WITH_TLS)
|
||||||
int mosquitto__hex2bin(const char *hex, unsigned char *bin, int bin_max_len)
|
int mosquitto__hex2bin(const char *hex, unsigned char *bin, int bin_max_len)
|
||||||
{
|
{
|
||||||
BIGNUM *bn = NULL;
|
BIGNUM *bn = NULL;
|
||||||
|
@ -33,7 +33,11 @@ void mosquitto__check_keepalive(struct mosquitto *mosq);
|
|||||||
uint16_t mosquitto__mid_generate(struct mosquitto *mosq);
|
uint16_t mosquitto__mid_generate(struct mosquitto *mosq);
|
||||||
FILE *mosquitto__fopen(const char *path, const char *mode, bool restrict_read);
|
FILE *mosquitto__fopen(const char *path, const char *mode, bool restrict_read);
|
||||||
|
|
||||||
#ifdef WITH_TLS_PSK
|
#ifdef WITH_TLS
|
||||||
|
int mosquitto__hex2bin_sha1(const char *hex, unsigned char **bin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WITH_TLS_PSK) || defined(WITH_TLS)
|
||||||
int mosquitto__hex2bin(const char *hex, unsigned char *bin, int bin_max_len);
|
int mosquitto__hex2bin(const char *hex, unsigned char *bin, int bin_max_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -910,6 +910,17 @@
|
|||||||
it. If not specified, pem keys are assumed</para>
|
it. If not specified, pem keys are assumed</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>tls_engine_kpass_sha</option> <replaceable>engine_kpass_sha</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>SHA1 of private key password when using an SSL engine.
|
||||||
|
Some SSL engines may require the usage of a password
|
||||||
|
in order to being accessed, like the TPM engine. Instead
|
||||||
|
of being prompted for the password, this option allows
|
||||||
|
a SHA1 hash of the password to be passed on to the
|
||||||
|
engine directly, without user interaction.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>crlfile</option> <replaceable>file path</replaceable></term>
|
<term><option>crlfile</option> <replaceable>file path</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
<arg choice='plain'><replaceable>pem</replaceable></arg>
|
<arg choice='plain'><replaceable>pem</replaceable></arg>
|
||||||
<arg choice='plain'><replaceable>engine</replaceable></arg>
|
<arg choice='plain'><replaceable>engine</replaceable></arg>
|
||||||
</group></arg>
|
</group></arg>
|
||||||
|
<arg><option>--tls-engine-kpass-sha</option> <replaceable>kpass-sha</replaceable></arg>
|
||||||
<arg><option>--insecure</option></arg>
|
<arg><option>--insecure</option></arg>
|
||||||
</arg>
|
</arg>
|
||||||
<arg>
|
<arg>
|
||||||
@ -204,6 +205,18 @@
|
|||||||
<para>See also <option>--tls-engine</option>.</para>
|
<para>See also <option>--tls-engine</option>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--tls-engine-kpass-sha</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>SHA1 of private key password when using an SSL engine.
|
||||||
|
Some SSL engines may require the usage of a password
|
||||||
|
in order to being accessed, like the TPM engine. Instead
|
||||||
|
of being prompted for the password, this option allows
|
||||||
|
a SHA1 hash of the password to be passed on to the
|
||||||
|
engine directly, without user interaction.</para>
|
||||||
|
<para>See also <option>--tls-engine</option>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-d</option></term>
|
<term><option>-d</option></term>
|
||||||
<term><option>--debug</option></term>
|
<term><option>--debug</option></term>
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
<arg choice='plain'><replaceable>pem</replaceable></arg>
|
<arg choice='plain'><replaceable>pem</replaceable></arg>
|
||||||
<arg choice='plain'><replaceable>engine</replaceable></arg>
|
<arg choice='plain'><replaceable>engine</replaceable></arg>
|
||||||
</group></arg>
|
</group></arg>
|
||||||
|
<arg><option>--tls-engine-kpass-sha</option> <replaceable>kpass-sha</replaceable></arg>
|
||||||
<arg><option>--insecure</option></arg>
|
<arg><option>--insecure</option></arg>
|
||||||
</arg>
|
</arg>
|
||||||
<arg>
|
<arg>
|
||||||
@ -214,6 +215,18 @@
|
|||||||
<para>See also <option>--tls-engine</option>.</para>
|
<para>See also <option>--tls-engine</option>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--tls-engine-kpass-sha</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>SHA1 of private key password when using an SSL engine.
|
||||||
|
Some SSL engines may require the usage of a password
|
||||||
|
in order to being accessed, like the TPM engine. Instead
|
||||||
|
of being prompted for the password, this option allows
|
||||||
|
a SHA1 hash of the password to be passed on to the
|
||||||
|
engine directly, without user interaction.</para>
|
||||||
|
<para>See also <option>--tls-engine</option>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-C</option></term>
|
<term><option>-C</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
17
src/conf.c
17
src/conf.c
@ -299,6 +299,7 @@ void config__cleanup(struct mosquitto__config *config)
|
|||||||
mosquitto__free(config->listeners[i].crlfile);
|
mosquitto__free(config->listeners[i].crlfile);
|
||||||
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_sha);
|
||||||
#ifdef WITH_WEBSOCKETS
|
#ifdef WITH_WEBSOCKETS
|
||||||
if(!config->listeners[i].ws_context) /* libwebsockets frees its own SSL_CTX */
|
if(!config->listeners[i].ws_context) /* libwebsockets frees its own SSL_CTX */
|
||||||
#endif
|
#endif
|
||||||
@ -436,6 +437,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
|
|||||||
|| config->default_listener.keyfile
|
|| config->default_listener.keyfile
|
||||||
|| config->default_listener.tls_engine
|
|| config->default_listener.tls_engine
|
||||||
|| config->default_listener.tls_keyform != mosq_k_pem
|
|| config->default_listener.tls_keyform != mosq_k_pem
|
||||||
|
|| config->default_listener.tls_engine_kpass_sha
|
||||||
|| config->default_listener.ciphers
|
|| config->default_listener.ciphers
|
||||||
|| config->default_listener.psk_hint
|
|| config->default_listener.psk_hint
|
||||||
|| config->default_listener.require_certificate
|
|| config->default_listener.require_certificate
|
||||||
@ -488,6 +490,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
|
|||||||
config->listeners[config->listener_count-1].tls_version = config->default_listener.tls_version;
|
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_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].tls_keyform = config->default_listener.tls_keyform;
|
||||||
|
config->listeners[config->listener_count-1].tls_engine_kpass_sha = config->default_listener.tls_engine_kpass_sha;
|
||||||
config->listeners[config->listener_count-1].cafile = config->default_listener.cafile;
|
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].capath = config->default_listener.capath;
|
||||||
config->listeners[config->listener_count-1].certfile = config->default_listener.certfile;
|
config->listeners[config->listener_count-1].certfile = config->default_listener.certfile;
|
||||||
@ -1108,6 +1111,20 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
|
|||||||
mosquitto__free(keyform);
|
mosquitto__free(keyform);
|
||||||
#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, "tls_engine_kpass_sha")){
|
||||||
|
#ifdef WITH_TLS
|
||||||
|
if(reload) continue; // Listeners not valid for reloading.
|
||||||
|
char *kpass_sha = NULL, *kpass_sha_bin = NULL;
|
||||||
|
if(conf__parse_string(&token, "tls_engine_kpass_sha", &kpass_sha, saveptr)) return MOSQ_ERR_INVAL;
|
||||||
|
if(mosquitto__hex2bin_sha1(kpass_sha, (unsigned char**)&kpass_sha_bin) != MOSQ_ERR_SUCCESS){
|
||||||
|
mosquitto__free(kpass_sha);
|
||||||
|
return MOSQ_ERR_INVAL;
|
||||||
|
}
|
||||||
|
cur_listener->tls_engine_kpass_sha = kpass_sha_bin;
|
||||||
|
mosquitto__free(kpass_sha);
|
||||||
|
#else
|
||||||
|
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available.");
|
||||||
#endif
|
#endif
|
||||||
}else if(!strcmp(token, "ciphers")){
|
}else if(!strcmp(token, "ciphers")){
|
||||||
#ifdef WITH_TLS
|
#ifdef WITH_TLS
|
||||||
|
@ -226,6 +226,7 @@ struct mosquitto__listener {
|
|||||||
char *keyfile;
|
char *keyfile;
|
||||||
char *tls_engine;
|
char *tls_engine;
|
||||||
enum _mosquitto_keyform tls_keyform;
|
enum _mosquitto_keyform tls_keyform;
|
||||||
|
char *tls_engine_kpass_sha;
|
||||||
char *ciphers;
|
char *ciphers;
|
||||||
char *psk_hint;
|
char *psk_hint;
|
||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
|
18
src/net.c
18
src/net.c
@ -501,7 +501,23 @@ int net__socket_listen(struct mosquitto__listener *listener)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(listener->tls_keyform == mosq_k_engine){
|
if(listener->tls_keyform == mosq_k_engine){
|
||||||
EVP_PKEY *pkey = ENGINE_load_private_key(engine, listener->keyfile, net__get_ui_method(), NULL);
|
UI_METHOD *ui_method = net__get_ui_method();
|
||||||
|
if(listener->tls_engine_kpass_sha){
|
||||||
|
if(!ENGINE_ctrl_cmd(engine, ENGINE_SECRET_MODE, ENGINE_SECRET_MODE_SHA, NULL, NULL, 0)){
|
||||||
|
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set engine secret mode sha");
|
||||||
|
COMPAT_CLOSE(sock);
|
||||||
|
ENGINE_FINISH(engine);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(!ENGINE_ctrl_cmd(engine, ENGINE_PIN, 0, listener->tls_engine_kpass_sha, NULL, 0)){
|
||||||
|
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set engine pin");
|
||||||
|
COMPAT_CLOSE(sock);
|
||||||
|
ENGINE_FINISH(engine);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ui_method = NULL;
|
||||||
|
}
|
||||||
|
EVP_PKEY *pkey = ENGINE_load_private_key(engine, listener->keyfile, ui_method, NULL);
|
||||||
if(!pkey){
|
if(!pkey){
|
||||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load engine private key file \"%s\".", listener->keyfile);
|
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load engine private key file \"%s\".", listener->keyfile);
|
||||||
COMPAT_CLOSE(sock);
|
COMPAT_CLOSE(sock);
|
||||||
|
Loading…
Reference in New Issue
Block a user