Fix legacy WSS certificate support and receive retries
Share the APP/kernel TLS profile, enable ECDSA and AES-GCM, and use RTC time for certificate validation. Fix WANT_READ/WANT_WRITE handling during WebSocket upgrade and add ABI, certificate, and receive regression checks.
This commit is contained in:
+29
-9
@@ -1,16 +1,16 @@
|
||||
# 旧板 WSS 适配与联调
|
||||
|
||||
本次修改位于 `legacy-board-wss`(基于 `legacy-board`),默认地址为 `wss://banban.api.talkingq.com:443/ws`。沿用无 GNSS、默认音量 100 的旧板配置。本次只修改 APP;复用此前支持旧板的内核和其中的 mbedTLS API。
|
||||
本次修改位于 `legacy-board-wss`(基于 `legacy-board`),默认地址为 `wss://banban.api.talkingq.com:443/ws`。沿用无 GNSS、默认音量 100 的旧板配置。上板暴露内核缺少 ECDSA 后,已补齐内核 TLS 能力并统一 APP/内核配置;本次必须更新内核和 APP。
|
||||
|
||||
## 后台实测(2026-09-16)
|
||||
|
||||
| 地址 | 结果 |
|
||||
| --- | --- |
|
||||
| `wss://banban.api.talkingq.com:443/ws` | TLS 1.2、证书链、域名校验通过;WebSocket Upgrade 返回 HTTP 404 |
|
||||
| `wss://banban.api.talkingq.com:443/ws` | 11:32 复测:TLS 1.2、证书链、域名、WebSocket Accept 校验通过,返回 HTTP 101;此前 404 已解决 |
|
||||
| `wss://banban.api.talkingq.com:8080/ws` | TLS 握手失败,端口未提供可用的 TLS 服务 |
|
||||
| `ws://banban.api.talkingq.com:8080/ws` | 明文 Upgrade 返回 HTTP 101,Accept 值正确 |
|
||||
|
||||
因此 8080 当前是可用的明文 WebSocket 服务,不能通过把 URL 的 `ws` 改成 `wss` 就获得加密。后台需要在 HTTPS 入口配置 `/ws` 转发,或提供另一个已经启用 TLS 的 WebSocket 入口。404 的准确原因仍需后台检查路由配置。测试没有发送设备身份或业务数据,也没有修改服务器。
|
||||
8080 当前是明文 WebSocket 服务,443 的 WSS 入口已可用。测试没有发送设备身份或业务数据,也没有修改服务器。
|
||||
|
||||
若 nginx 与 8080 服务部署在同一主机,可在现有 `listen 443 ssl` 的域名配置中参考以下转发(由后台按真实部署调整):
|
||||
|
||||
@@ -25,10 +25,24 @@ location /ws {
|
||||
}
|
||||
```
|
||||
|
||||
修复后重新运行 `powershell.exe -NoProfile -ExecutionPolicy Bypass -File tools\probe_talkingq_wss.ps1`。必须得到有效 HTTP 101 和匹配的 `Sec-WebSocket-Accept`;仅 HTTPS 打得开或证书正常不代表 WebSocket 已可用。
|
||||
可重新运行 `powershell.exe -NoProfile -ExecutionPolicy Bypass -File tools\probe_talkingq_wss.ps1`。必须得到有效 HTTP 101 和匹配的 `Sec-WebSocket-Accept`;仅 HTTPS 打得开或证书正常不代表 WebSocket 已可用。
|
||||
|
||||
## 上板 -9774 的修复
|
||||
|
||||
11:42 日志中,联网和 MQTT 正常,WSS 在解析根 CA 时返回 `-9774`(`-0x262E`:未知签名算法)。ISRG Root X2 使用 ECDSA/SHA-384,原内核 mini TLS 配置没有编译 ECDSA。此前主机 OpenSSL 验证通过,仅能证明证书链有效,不能证明内核支持它。
|
||||
|
||||
- 新增 `ql-config/config/talkingq_mbedtls_config.h`,由 APP 和内核 mini profile 共用;增加 ECDSA、ECDHE-ECDSA、AES-GCM 和证书日期校验。
|
||||
- 内核缺失的 `mbedtls/ecdsa.h` 从 APP 中同版本 2.28.9 SDK 头文件补入。
|
||||
- ARMCC 编译内核头文件、GCC 编译 APP 头文件,对比 10 种 TLS 类型的大小和关键字段偏移,防止调用内核 API 时结构体布局不一致。
|
||||
- 内核的 `GetCurrentCompTime()` 在此产品上是空 shim。X.509 时间检查改用 `mbedtls_time()` 的真实 RTC 时间和 UTC 转换,保留证书日期验证。
|
||||
- 日志增加失败阶段及十六进制错误码;CA 解析成功会输出 `WSS root CA parsed successfully`。
|
||||
|
||||
不能仅刷 APP 修复本次问题,也不能只用未修改配置的旧内核重新打包。
|
||||
|
||||
## 固件行为
|
||||
|
||||
2026-09-16 14:06 板端已通过根 CA 解析、TLS 握手、服务器证书和域名校验。后续 `recv data failed` / `HTTP 0` 定位到 APP 接收函数:TLS 返回 WANT_READ/WANT_WRITE 后跳出循环,错误变量仍为初始值 -1,导致误断线。现已在该分支明确清除错误状态,由原握手循环继续等待;真实 EOF、TLS 错误和握手超时仍会结束连接。
|
||||
|
||||
- `inc/talkingq_wss.h` 集中定义默认地址。解析独立处理域名、端口、路径,默认端口 443、无路径时默认 `/ws`;拒绝明文 URL、非法端口、过长字段和 CR/LF 注入。现有存储容量为 64 字节;不支持 IPv6 字面量。
|
||||
- `hal_os_get_talkingq_url()` 在没有保存地址、或保存值与已知旧默认地址完全匹配时,返回新默认 WSS 地址。此迁移在读取时生效,不改写 Flash。自定义地址保留;自定义明文地址会明确失败,不自动降级。
|
||||
- 启用 librws 的 mbedTLS 实现,统一公共和私有头文件中的宏。TCP 继续使用现有蜂窝 PDP profile 1,避免 SDK 定制 `mbedtls_net_connect` 的 CID/端口 ABI 差异。
|
||||
@@ -57,22 +71,28 @@ location /ws {
|
||||
|
||||
```bat
|
||||
tools\test_wss.cmd
|
||||
ql-cross-tool\win32\owtoolchain\Python\python.exe tools\check_mbedtls_abi.py
|
||||
build.bat kernel
|
||||
build.bat app
|
||||
build.bat firmware
|
||||
```
|
||||
|
||||
主机测试使用 MSVC 编译实际 URL 和握手解析源码;另从真实实现提取 TLS 写入和取消连接函数,注入桩测试短写、重试、超时、时钟回绕和资源释放。解析测试覆盖合法地址、非法端口、明文拒绝、缓冲区边界、旧地址识别、每个响应头分片边界、非 101、错误/重复 Accept、缺失 Upgrade/Connection 和响应大小上限。
|
||||
主机测试使用 MSVC 编译实际 URL 和握手解析源码;另从真实实现提取 TLS 写入和取消连接函数,注入桩测试短写、重试、超时、时钟回绕和资源释放。`tools/test_wss_receive.py` 提取实际接收和握手等待函数,结合实际 HTTP 解析器验证 WANT_READ/WANT_WRITE、分片 101、响应后帧数据保留、超时和时钟回绕、EOF/真实错误、空 TLS 上下文及错误 Accept;修复前可复现误断线,修复后通过。解析测试覆盖合法地址、非法端口、明文拒绝、缓冲区边界、旧地址识别、每个响应头分片边界、非 101、错误/重复 Accept、缺失 Upgrade/Connection 和响应大小上限。
|
||||
|
||||
导出后运行 `ql-cross-tool\win32\owtoolchain\Python\python.exe tools\verify_wss_package.py`,核对 ZIP CRC、APP/内核与当前构建的字节一致性、无 GNSS 入口以及 WSS 链接符号。SDK 有既有编译警告,不能仅凭外层批处理退出码认定成功。
|
||||
在 Visual Studio 开发者终端运行 `ql-cross-tool\win32\owtoolchain\Python\python.exe tools\test_mbedtls_cert.py`,使用 SDK 实际 crypto/X.509 源码和共享配置验证内置根 CA、当前服务器证书链、错误域名、空信任库、过期/尚未生效日期,以及 AES-GCM 标准测试向量。测试中的分配器、UTC 时钟和日志适配到 Windows,文件读取由测试程序完成;没有替换证书算法实现。默认使用 `artifacts/wss/retest-443/chain-0.pem` 至 `chain-2.pem`,可把探测输出目录作为脚本参数。
|
||||
|
||||
测试包位于 `artifacts/wss/EG800AKCN_11LG-legacy-wss.zip`。这是完整多分区烧录包,不是 APP-only 包。原可回退的旧板包保留在 `artifacts/legacy-no-gnss/`。
|
||||
导出到下述路径后运行 `ql-cross-tool\win32\owtoolchain\Python\python.exe tools\verify_wss_package.py`,核对 ZIP CRC、APP/内核与当前构建的字节一致性、无 GNSS 入口以及内核 ECDSA/GCM/日期校验符号。SDK 有既有编译警告,不能仅凭外层批处理退出码认定成功。
|
||||
|
||||
最新修复测试包位于 `artifacts/wss/recv-fix/EG800AKCN_11LG-legacy-wss-recv.zip`,标准输出为 `target/EG800AKCN_11LG/EG800AKCN_11LG.zip`,两者字节一致。这是完整多分区烧录包,内核与 ECC/RTC 修复包一致,APP 增加接收重试修复。在保留已构建的 ECC/RTC 内核的当前工作区,本次仅需 `build.bat app` 和 `build.bat firmware`;全新工作区仍需先构建内核。校验命令为 `ql-cross-tool\win32\owtoolchain\Python\python.exe tools\verify_wss_package.py artifacts/wss/recv-fix/EG800AKCN_11LG-legacy-wss-recv.zip`。
|
||||
|
||||
`ecc-fix/EG800AKCN_11LG-legacy-wss-ecc.zip` 保留用于对照接收错误。原 `artifacts/wss/EG800AKCN_11LG-legacy-wss.zip` 存在缺失 ECDSA 的问题,请勿用于验证本次修复。旧板明文 WS 包仍保留在 `artifacts/legacy-no-gnss/`。
|
||||
|
||||
## 上板验收
|
||||
|
||||
目前未烧录、未完成设备业务联调,且服务器 443 `/ws` 尚返回 404。确认后台转发修复后,再检查:
|
||||
443 `/ws` 已通过主机握手测试;ECC/RTC 修复已在板端通过 TLS 验证,接收修复包仍需上板检查:
|
||||
|
||||
1. 无 GNSS 旧板正常启动、蜂窝网络就绪、RTC 时间正确。
|
||||
2. 出现 `WSS TLS handshake and certificate/hostname verification passed`。
|
||||
2. 先出现 `WSS root CA parsed successfully`,再出现 `WSS TLS handshake and certificate/hostname verification passed`。
|
||||
3. 出现 `WebSocket upgrade verified: HTTP 101` 和 `ws connect okay`。
|
||||
4. 服务器确认原设备鉴权成功,再测试收发音频、断网重连和休眠唤醒。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user