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

Security Regression: Mosquitto client connects without verifying broker CA file #2130

Closed
becz opened this issue Mar 11, 2021 · 2 comments
Closed
Milestone

Comments

@becz
Copy link

becz commented Mar 11, 2021

Hello,

with mosquitto 1.6.12 and openssl 1.0.2g I have an issue with TLS handshake. The handshake is performed even with an empty ca file. It seems like this behaviour was introduced since 1.5.7

Steps to reproduce:

  • Use broker with tls enabled and without client authentication (like test,mosquitto.org:8883)
  • Create empty ca file on client side (e.g. touch InvalidCa.crt)
  • Start example project (NameOfBinary PathToCaFile)

--> After starting the example project, the call of mosquitto_connect_async will fail and it returns 8 (A TLS error occurred.). Also error message "Error: Unable to load CA certificates, check cafile "InvalidCa.crt"." is logged.
--> Then mosquitto_loop_start is called. Mosquitto will connect to the broker without complaining about the invalid ca file and without verifying the peer.

If mosquitto 1.4.12 is used, mosquitto client library will constantly try to reconnect to the broker after calling mosquitto_loop_start. This is the required behaviour for my use case.

For me it seems like that initialisation is skipped in case of reconnect due to following code path:

if(!mosq->ssl_ctx_defaults){

Example program:

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <mosquitto.h>

static int run = 1;

void handle_signal(int s)
{
	run = 0;
}

void connect_callback(struct mosquitto *mosq, void *obj, int result)
{
	printf("Connected!\n");
}

void disconnect_callback(struct mosquitto *mosq, void *obj, int result)
{
	printf("Disconnected! (%i)\n", result);
}

void message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
	printf("Message!\n");
}

void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
{
	printf("Log: %s\n", str);
}

int main(int argc, char *argv[])
{
	struct mosquitto *mosq = NULL;
	char clientid[24]="myLoopTest";
	char *host = "test.mosquitto.org";
	uint32_t port = 8883;
	int rc = 0;
	int major,minor,bugfix;
	signal(SIGTERM, handle_signal);
	signal(SIGINT, handle_signal);

	mosquitto_lib_init();
	mosquitto_lib_version(&major,&minor,&bugfix);
	printf("library version: %i.%i.%i\n",major,minor,bugfix);
	mosq = mosquitto_new(clientid, true, NULL);
	rc = mosquitto_tls_set(mosq,argv[1],NULL,NULL,NULL,NULL);
	printf("mosquitto_tls_set returned: %i (%s)\n", rc, mosquitto_strerror(rc));
		
	if(mosq){
		mosquitto_connect_callback_set(mosq, connect_callback);
		mosquitto_disconnect_callback_set(mosq, disconnect_callback);
		mosquitto_message_callback_set(mosq, message_callback);
		mosquitto_log_callback_set(mosq, my_log_callback);
		
		rc =mosquitto_connect_async(mosq, host, port, 10);
		printf("mosquitto_connect_async returned: %i (%s)\n",rc,mosquitto_strerror(rc));
		
		rc = mosquitto_loop_start(mosq);	
		printf("mosquitto_loop_start returned: %i (%s)\n",rc,mosquitto_strerror(rc));

		while(run==1){
		}
		printf("\nExiting\n");
		mosquitto_destroy(mosq);
		mosquitto_lib_cleanup();
		return rc;
	}
}

Output of example program:

library version: 1.6.12
mosquitto_tls_set returned: 0 (No error.)
Log: Error: Unable to load CA certificates, check cafile "InvalidCa.crt".
mosquitto_connect_async returned: 8 (A TLS error occurred.)
mosquitto_loop_start returned: 0 (No error.)
Log: Client myLoopTest sending CONNECT
Log: Client myLoopTest received CONNACK (0)
Connected!
Log: Client myLoopTest sending PINGREQ
Log: Client myLoopTest received PINGRESP

Best regards

@ralight
Copy link
Contributor

ralight commented Mar 11, 2021

Thanks for the report. I'm preparing releases with this fix in.

@ralight ralight closed this as completed Mar 11, 2021
@ralight ralight added this to the 2.0.9 milestone Mar 11, 2021
ralight added a commit that referenced this issue Mar 11, 2021
ralight added a commit that referenced this issue Mar 11, 2021
ralight added a commit that referenced this issue Mar 11, 2021
@mm-ark
Copy link

mm-ark commented Mar 12, 2021

Thank you very much for the quick reaction and fix!

I run further tests with new library 1.6.14 and observed further "unexpected connect"
which is not present with library 1.4.15

I did following:

  1. Use broker with tls enabled and without client authentication (like test,mosquitto.org:8883)
  2. Create empty ca file on client side (e.g. touch InvalidCa.crt)
  3. Start example project (NameOfBinary PathToCaFile)
    --- observe library does not connect --- (OK)
  4. Write valid certificate for the broker into InvalidCa.crt
    --- observe library connected to broker --- (OK)
  5. Make sure library disconnects (e.g. switch ethernet off for a while)
  6. Write certificate of "other broker" into InvalidCa.crt
  7. Make sure library can connect (e.g. switch ethernet on)
    --- observe library connected to broker --- (UNEXPECTED)

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants