Library will no longer allow single level wildcard certificates, e.g. *.com

This commit is contained in:
Roger A. Light 2023-06-14 15:15:33 +01:00
parent b76c3c7820
commit 284db04bc3
6 changed files with 165 additions and 2 deletions

1
.gitignore vendored
View File

@ -81,6 +81,7 @@ test/unit/mosq_test
test/unit/persist_read_test
test/unit/persist_write_test
test/unit/subs_test
test/unit/tls_test
test/unit/out/
www/cache/

View File

@ -5,7 +5,8 @@ Security:
- Broker will now reject Will messages that attempt to publish to $CONTROL/.
- Broker now validates usernames provided in a TLS certificate or TLS-PSK
identity are valid UTF-8.
- Fix potential crash when loading invalid persitence file.
- Fix potential crash when loading invalid persistence file.
- Library will no longer allow single level wildcard certificates, e.g. *.com
Broker:
- Fix $SYS messages being expired after 60 seconds and hence unchanged values

View File

@ -105,6 +105,17 @@ static int mosquitto__cmp_hostname_wildcard(char *certname, const char *hostname
break;
}
}
len = strlen(hostname);
int dotcount = 0;
for(i=0; i<len-1; i++){
if(hostname[i] == '.'){
dotcount++;
}
}
if(dotcount < 1){
/* Exclude e.g. *.com, allow e.g. *.example.com */
return 1;
}
return strcasecmp(certname, hostname);
}else{
return strcasecmp(certname, hostname);

View File

@ -82,6 +82,10 @@ PERSIST_WRITE_OBJS = \
utf8_mosq.o \
util_mosq.o
TLS_TEST_OBJS = \
tls_test.o \
tls_stubs.o
SUBS_TEST_OBJS = \
subs_test.o \
subs_stubs.o
@ -112,6 +116,9 @@ persist_write_test : ${PERSIST_WRITE_TEST_OBJS} ${PERSIST_WRITE_OBJS}
subs_test : ${SUBS_TEST_OBJS} ${SUBS_OBJS}
$(CROSS_COMPILE)$(CC) $(LDFLAGS) -o $@ $^ $(LDADD)
tls_test : ${TLS_TEST_OBJS} ${TLS_OBJS}
$(CROSS_COMPILE)$(CC) $(LDFLAGS) -o $@ $^ $(LDADD) -lssl -lcrypto
bridge_topic.o : ../../src/bridge_topic.c
$(CROSS_COMPILE)$(CC) $(CPPFLAGS) $(CFLAGS) -DWITH_BROKER -DWITH_BRIDGE -c -o $@ $^
@ -167,10 +174,11 @@ util_topic.o : ../../lib/util_topic.c
utf8_mosq.o : ../../lib/utf8_mosq.c
$(CROSS_COMPILE)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $^
build : mosq_test bridge_topic_test persist_read_test persist_write_test subs_test
build : mosq_test bridge_topic_test persist_read_test persist_write_test subs_test tls_test
test-lib : build
./mosq_test
./tls_test
test-broker : build
./bridge_topic_test

40
test/unit/tls_stubs.c Normal file
View File

@ -0,0 +1,40 @@
#include "config.h"
#include <time.h>
#include <logging_mosq.h>
int tls_ex_index_mosq;
struct mosquitto_db{
};
int log__printf(struct mosquitto *mosq, unsigned int priority, const char *fmt, ...)
{
UNUSED(mosq);
UNUSED(priority);
UNUSED(fmt);
return 0;
}
time_t mosquitto_time(void)
{
return 123;
}
int net__socket_close(struct mosquitto_db *db, struct mosquitto *mosq)
{
UNUSED(db);
UNUSED(mosq);
return MOSQ_ERR_SUCCESS;
}
int send__pingreq(struct mosquitto *mosq)
{
UNUSED(mosq);
return MOSQ_ERR_SUCCESS;
}

102
test/unit/tls_test.c Normal file
View File

@ -0,0 +1,102 @@
#include <CUnit/CUnit.h>
#include <CUnit/Basic.h>
#define WITH_TLS
#include "tls_mosq.c"
//static int mosquitto__cmp_hostname_wildcard(char *certname, const char *hostname)
void hostname_cmp_helper(char *certname, const char *hostname, int expected)
{
int rc = mosquitto__cmp_hostname_wildcard(certname, hostname);
CU_ASSERT_EQUAL(rc, expected);
if(rc != expected){
printf("%d || %d\n", rc, expected);
}
}
void TEST_tls_hostname_compare_null(void)
{
hostname_cmp_helper(NULL, "localhost", 1);
hostname_cmp_helper("localhost", NULL, 1);
hostname_cmp_helper(NULL, NULL, 1);
}
void TEST_tls_hostname_compare_simple(void)
{
hostname_cmp_helper("localhost", "localhost", 0);
hostname_cmp_helper("localhost", "localhose", 15);
}
void TEST_tls_hostname_compare_bad_wildcard_format(void)
{
hostname_cmp_helper("**localhost", "localhost", 1);
hostname_cmp_helper("*,localhost", "localhost", 1);
hostname_cmp_helper("*.", "localhost", 1);
}
void TEST_tls_hostname_compare_invalid_wildcard(void)
{
hostname_cmp_helper("*.com", "example.com", 1);
hostname_cmp_helper("*.com", "example.org", 1);
hostname_cmp_helper("*.org", "example.org", 1);
}
void TEST_tls_hostname_compare_good_wildcard(void)
{
hostname_cmp_helper("*.example.com", "test.example.com", 0);
hostname_cmp_helper("*.example.com", "test.example.org", -12);
hostname_cmp_helper("*.example.org", "test.example.org", 0);
}
/* ========================================================================
* TEST SUITE SETUP
* ======================================================================== */
int main(int argc, char *argv[])
{
CU_pSuite test_suite = NULL;
unsigned int fails;
UNUSED(argc);
UNUSED(argv);
if(CU_initialize_registry() != CUE_SUCCESS){
printf("Error initializing CUnit registry.\n");
return 1;
}
test_suite = CU_add_suite("Subs", NULL, NULL);
if(!test_suite){
printf("Error adding CUnit TLS test suite.\n");
CU_cleanup_registry();
return 1;
}
if(0
|| !CU_add_test(test_suite, "TLS hostname compare null", TEST_tls_hostname_compare_null)
|| !CU_add_test(test_suite, "TLS hostname compare simple", TEST_tls_hostname_compare_simple)
|| !CU_add_test(test_suite, "TLS hostname compare bad wildcard format", TEST_tls_hostname_compare_bad_wildcard_format)
|| !CU_add_test(test_suite, "TLS hostname compare invalid wildcard", TEST_tls_hostname_compare_invalid_wildcard)
|| !CU_add_test(test_suite, "TLS hostname compare good wildcard", TEST_tls_hostname_compare_good_wildcard)
){
printf("Error adding TLS CUnit tests.\n");
CU_cleanup_registry();
return 1;
}
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
fails = CU_get_number_of_failures();
CU_cleanup_registry();
return (int)fails;
}