Add verified WSS transport for legacy boards

Configure the default WSS endpoint and ISRG Root X2 trust anchor, preserve device authentication, enforce TLS and WebSocket handshake validation, and handle partial I/O and connection cleanup. Add host tests, server probes, package verification and integration documentation. Backend 443 /ws still returns HTTP 404; on-device validation remains pending.
This commit is contained in:
chenjintao
2026-09-16 11:23:33 +08:00
parent 4b565958f9
commit 3e463f57b6
23 changed files with 809 additions and 396 deletions
+58
View File
@@ -0,0 +1,58 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "talkingq_wss.h"
#include "rws_handshake.h"
static const char accept[] = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=";
static const char good[] = "HTTP/1.1 101 Switching Protocols\r\n"
"uPgRaDe: WebSocket\r\nConnection: keep-alive, Upgrade\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
int main(void)
{
char host[64], path[128], data[RWS_HANDSHAKE_MAX + 20];
int port, status;
size_t i, header;
const char *bad[] = {"ws://example.com/ws", "https://example.com/ws", "wss:///ws",
"wss://user@example.com/ws", "wss://example.com:0/ws", "wss://example.com:65536/ws",
"wss://example.com:-1/ws", "wss://example.com:/ws", "wss://example.com:abc/ws",
"wss://example.com/ws#frag", "wss://example.com/ws\r\nInjected:yes",
"wss://example.com:99999999999999999999999/ws", "wss://example.com/bad path"};
assert(!talkingq_parse_wss_url(TALKINGQ_WSS_URL, host, sizeof(host), &port, path, sizeof(path)));
assert(!strcmp(host, "banban.api.talkingq.com") && port == 443 && !strcmp(path, "/ws"));
assert(!talkingq_parse_wss_url("wss://example.com", host, sizeof(host), &port, path, sizeof(path)));
assert(port == 443 && !strcmp(path, "/ws"));
assert(!talkingq_parse_wss_url("wss://example.com:8080/ws?x=y", host, sizeof(host), &port, path, sizeof(path)));
assert(port == 8080 && !strcmp(path, "/ws?x=y"));
for (i = 0; i < sizeof(bad)/sizeof(bad[0]); ++i)
assert(talkingq_parse_wss_url(bad[i], host, sizeof(host), &port, path, sizeof(path)) == -1);
assert(talkingq_parse_wss_url(TALKINGQ_WSS_URL, host, 3, &port, path, sizeof(path)) == -1);
assert(talkingq_parse_wss_url(TALKINGQ_WSS_URL, host, sizeof(host), &port, path, 3) == -1);
assert(talkingq_is_legacy_ws_url("ws://101.35.224.118:8080"));
assert(talkingq_is_legacy_ws_url("ws://101.35.224.118:8080/ws"));
assert(!talkingq_is_legacy_ws_url(TALKINGQ_WSS_URL));
assert(!talkingq_is_legacy_ws_url("ws://custom.example:8080/ws"));
/* Every possible TLS fragment boundary, with no NUL terminator available. */
for (i = 0; i < sizeof(good)-1; ++i) {
memset(data, 'X', sizeof(data));
memcpy(data, good, i);
assert(rws_check_handshake(data, i, accept, &header, &status) == 0);
}
memcpy(data, good, sizeof(good)-1);
((unsigned char *)data)[sizeof(good)-1] = 0x81; data[sizeof(good)] = 0;
assert(rws_check_handshake(data, sizeof(good)+1, accept, &header, &status) == 1);
assert(status == 101 && header == sizeof(good)-1);
assert(rws_check_handshake(data, sizeof(good)-1, "wrong", &header, &status) == -1);
memcpy(data + 9, "404", 3);
assert(rws_check_handshake(data, sizeof(good)-1, accept, &header, &status) == -1 && status == 404);
strcpy(data, "HTTP/1.1 101 OK\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n");
assert(rws_check_handshake(data, strlen(data), accept, &header, &status) == -1);
memcpy(data, good, sizeof(good));
strcpy(data + sizeof(good)-3, "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n");
assert(rws_check_handshake(data, strlen(data), accept, &header, &status) == -1);
memset(data, 'X', sizeof(data));
assert(rws_check_handshake(data, sizeof(data), accept, &header, &status) == -1);
puts("PASS: WSS URL policy, legacy migration, fragmented upgrade, status, accept, headers and limits");
return 0;
}