3535
3636#ifdef WOLFMQTT_BROKER
3737
38+ /* Secure memory zeroing - prevents compiler dead-store elimination */
39+ #ifdef ENABLE_MQTT_TLS
40+ #include <wolfssl/wolfcrypt/memory.h>
41+ #define BROKER_FORCE_ZERO (mem , len ) wc_ForceZero(mem, (word32)(len))
42+ #else
43+ /* Local implementation matching wolfCrypt's ForceZero */
44+ static void BrokerForceZero (void * mem , word32 len )
45+ {
46+ volatile byte * p = (volatile byte * )mem ;
47+ word32 i ;
48+ for (i = 0 ; i < len ; i ++ ) {
49+ p [i ] = 0 ;
50+ }
51+ }
52+ #define BROKER_FORCE_ZERO (mem , len ) BrokerForceZero(mem, (word32)(len))
53+ #endif
54+
3855/* -------------------------------------------------------------------------- */
3956/* Platform includes */
4057/* -------------------------------------------------------------------------- */
@@ -137,10 +154,14 @@ static int BrokerStrCompare(const char* a, const char* b)
137154 int result = 0 ;
138155 int len_a = (int )XSTRLEN (a );
139156 int len_b = (int )XSTRLEN (b );
140- int len = (len_a < len_b ) ? len_a : len_b ;
157+ int max_len = (len_a > len_b ) ? len_a : len_b ;
141158 int i ;
142- for (i = 0 ; i < len ; i ++ ) {
143- result |= (a [i ] ^ b [i ]);
159+ for (i = 0 ; i < max_len ; i ++ ) {
160+ /* Branchless index clamp: when i >= len, reads position 0.
161+ * Length mismatch is caught by the final XOR below. */
162+ int ia = i & ((i - len_a ) >> (sizeof (int ) * 8 - 1 ));
163+ int ib = i & ((i - len_b ) >> (sizeof (int ) * 8 - 1 ));
164+ result |= (a [ia ] ^ b [ib ]);
144165 }
145166 result |= (len_a ^ len_b );
146167 return result ;
@@ -164,7 +185,7 @@ static void BrokerStore_StringSensitive(char* dst, int max_len,
164185 const char * src , word16 src_len )
165186{
166187 /* Wipe old value before overwriting */
167- XMEMSET (dst , 0 , max_len );
188+ BROKER_FORCE_ZERO (dst , max_len );
168189 if (src_len >= (word16 )max_len ) {
169190 src_len = (word16 )(max_len - 1 );
170191 }
@@ -177,7 +198,7 @@ static void BrokerStore_String(char** dst_ptr,
177198{
178199 if (* dst_ptr != NULL ) {
179200 if (sensitive ) {
180- XMEMSET (* dst_ptr , 0 , XSTRLEN (* dst_ptr ) + 1 );
201+ BROKER_FORCE_ZERO (* dst_ptr , XSTRLEN (* dst_ptr ) + 1 );
181202 }
182203 WOLFMQTT_FREE (* dst_ptr );
183204 * dst_ptr = NULL ;
@@ -225,6 +246,9 @@ static int BrokerTls_Init(MqttBroker* broker)
225246 }
226247 else {
227248 ctx = wolfSSL_CTX_new (wolfSSLv23_server_method ());
249+ if (ctx != NULL ) {
250+ wolfSSL_CTX_SetMinVersion (ctx , WOLFSSL_TLSV1_2 );
251+ }
228252 }
229253 if (ctx == NULL ) {
230254 WBLOG_ERR (broker , "broker: wolfSSL_CTX_new failed" );
@@ -1203,21 +1227,21 @@ static void BrokerClient_Free(BrokerClient* bc)
12031227 }
12041228#ifdef WOLFMQTT_BROKER_AUTH
12051229 if (bc -> username ) {
1206- XMEMSET (bc -> username , 0 , XSTRLEN (bc -> username ) + 1 );
1230+ BROKER_FORCE_ZERO (bc -> username , XSTRLEN (bc -> username ) + 1 );
12071231 WOLFMQTT_FREE (bc -> username );
12081232 }
12091233 if (bc -> password ) {
1210- XMEMSET (bc -> password , 0 , XSTRLEN (bc -> password ) + 1 );
1234+ BROKER_FORCE_ZERO (bc -> password , XSTRLEN (bc -> password ) + 1 );
12111235 WOLFMQTT_FREE (bc -> password );
12121236 }
12131237#endif
12141238#ifdef WOLFMQTT_BROKER_WILL
12151239 if (bc -> will_topic ) {
1216- XMEMSET (bc -> will_topic , 0 , XSTRLEN (bc -> will_topic ) + 1 );
1240+ BROKER_FORCE_ZERO (bc -> will_topic , XSTRLEN (bc -> will_topic ) + 1 );
12171241 WOLFMQTT_FREE (bc -> will_topic );
12181242 }
12191243 if (bc -> will_payload ) {
1220- XMEMSET (bc -> will_payload , 0 , bc -> will_payload_len );
1244+ BROKER_FORCE_ZERO (bc -> will_payload , bc -> will_payload_len );
12211245 WOLFMQTT_FREE (bc -> will_payload );
12221246 }
12231247#endif
@@ -2468,6 +2492,11 @@ static int BrokerTopicMatch(const char* filter, const char* topic)
24682492 return 0 ;
24692493 }
24702494
2495+ /* [MQTT-4.7.2] Wildcard filters must not match $-prefixed topics */
2496+ if (* t == '$' && (* f == '+' || * f == '#' )) {
2497+ return 0 ;
2498+ }
2499+
24712500 while (* f && * t ) {
24722501 if (* f == '#' ) {
24732502 return (f [1 ] == '\0' );
@@ -3063,6 +3092,19 @@ static int BrokerHandle_Publish(BrokerClient* bc, int rx_len,
30633092 return rc ;
30643093 }
30653094
3095+ /* [MQTT-3.3.2-2] PUBLISH topic must not contain wildcard characters */
3096+ if (pub .topic_name && pub .topic_name_len > 0 ) {
3097+ word16 i ;
3098+ for (i = 0 ; i < pub .topic_name_len ; i ++ ) {
3099+ if (pub .topic_name [i ] == '+' || pub .topic_name [i ] == '#' ) {
3100+ WBLOG_ERR (broker ,
3101+ "broker: PUBLISH topic contains wildcard sock=%d" ,
3102+ (int )bc -> sock );
3103+ return MQTT_CODE_ERROR_BAD_ARG ;
3104+ }
3105+ }
3106+ }
3107+
30663108 /* Create null-terminated topic copy for matching/logging */
30673109 if (pub .topic_name && pub .topic_name_len > 0 ) {
30683110#ifdef WOLFMQTT_STATIC_MEMORY
@@ -3363,6 +3405,15 @@ static int BrokerClient_Process(MqttBroker* broker, BrokerClient* bc)
33633405 BrokerClient_Remove (broker , bc );
33643406 return 0 ;
33653407 }
3408+ /* [MQTT-3.1.0-2] Second CONNECT is a protocol violation */
3409+ if (type == MQTT_PACKET_TYPE_CONNECT && bc -> connected ) {
3410+ WBLOG_ERR (broker ,
3411+ "broker: second CONNECT on sock=%d [MQTT-3.1.0-2]" ,
3412+ (int )bc -> sock );
3413+ BrokerSubs_RemoveClient (broker , bc );
3414+ BrokerClient_Remove (broker , bc );
3415+ return 0 ;
3416+ }
33663417 switch (type ) {
33673418 case MQTT_PACKET_TYPE_CONNECT :
33683419 {
0 commit comments