Files
MeshCore/test/fixtures/mqtt_tls_security.cpp
T

72 lines
3.1 KiB
C++

#include <cassert>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <string>
#include <initializer_list>
#define MQTT_DEBUG_PRINTLN(...) ((void)0)
static constexpr int ESP_OK=0;
using esp_err_t=int;
const char* esp_err_to_name(int) { return "mock"; }
uint32_t millis() { return 123; }
const uint8_t rootca_bytes[16]={};
const uint8_t* rootca_crt_bundle_start=nullptr;
const uint8_t* rootca_crt_bundle_end=nullptr;
static bool s_ca_bundle_loaded=false;
struct Client {
int credentials=0, bundles=0, attaches=0; std::string server;
void setServer(const char* uri) { server=uri; }
void setCACertBundle(const uint8_t*, size_t) { ++bundles; }
void attachArduinoCACertBundle(bool value) { assert(value); ++attaches; }
void setCredentials(const char*, const char*) { ++credentials; }
};
struct MQTTBridge {
struct MQTTSlot {
char host[100]="broker.example", broker_uri[150]={};
char username[40]="user", password[40]="secret", audience[40]={};
char token[80]="signed-jwt"; char* auth_token=token;
uint16_t port=8883; Client* client=nullptr;
bool initial_connect_done=true; uint32_t last_reconnect_attempt=0;
} _slots[2];
Client clients[2]; int connects=0, tokens=0;
const char* _jwt_username="jwt";
MQTTBridge() { for (int i=0;i<2;++i) _slots[i].client=&clients[i]; }
bool createSlotAuthToken(int) { ++tokens; return true; }
int reconnectSlotClient(int) { ++connects; return ESP_OK; }
bool setupCustom(int);
};
@METHOD@
int main() {
for (const char* host : {"mqtts://broker", "wss://broker/path", "broker"}) {
for (bool jwt : {false, true}) {
MQTTBridge bridge; auto& slot=bridge._slots[0];
strcpy(slot.host, host); if(jwt) strcpy(slot.audience, "fleet-audience");
assert(!bridge.setupCustom(0));
assert(!slot.initial_connect_done && slot.last_reconnect_attempt==123);
assert(bridge.connects==0 && bridge.tokens==0 && bridge.clients[0].credentials==0);
}
}
// Port 443 infers WSS and needs verification too.
MQTTBridge wss; wss._slots[0].port=443; assert(!wss.setupCustom(0)); assert(wss.connects==0);
// Explicit plaintext is an operator choice; never silently downgrade TLS.
for (const char* host : {"mqtt://broker", "ws://broker/path", "broker"}) {
MQTTBridge plain; strcpy(plain._slots[0].host, host); plain._slots[0].port=1883;
assert(plain.setupCustom(0) && plain.connects==1 && plain.clients[0].credentials==1);
assert(plain.clients[0].bundles==0);
}
rootca_crt_bundle_start=rootca_bytes; rootca_crt_bundle_end=rootca_bytes+sizeof(rootca_bytes);
MQTTBridge trusted;
#ifdef PORTABLE_MQTT_OBSERVER
assert(!trusted.setupCustom(0) && trusted.connects==0); // bundle deliberately unlinked
#else
assert(trusted.setupCustom(0));
assert(s_ca_bundle_loaded && trusted.clients[0].bundles==1 && trusted.clients[0].credentials==1);
strcpy(trusted._slots[1].audience, "fleet-audience");
assert(trusted.setupCustom(1));
assert(trusted.clients[1].bundles==0 && trusted.clients[1].attaches==1);
assert(trusted.tokens==1 && trusted.connects==2);
assert(trusted.clients[0].server=="mqtts://broker.example:8883");
#endif
puts("MQTT custom TLS security regression checks passed");
}