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:
chenjintao
2026-09-16 14:19:55 +08:00
parent 3e463f57b6
commit 5c3e7eee6d
17 changed files with 1071 additions and 4433 deletions
@@ -314,7 +314,11 @@ rws_bool rws_socket_recv(_rws_socket *s)
goto _exit;
}
len = mbedtls_ssl_read(&(s->ssl->ssl_ctx), (unsigned char *)(s->payload_buff), RWS_RECEIVE_BUFF_SIZE);
if (len == MBEDTLS_ERR_SSL_WANT_READ || len == MBEDTLS_ERR_SSL_WANT_WRITE) break;
if (len == MBEDTLS_ERR_SSL_WANT_READ || len == MBEDTLS_ERR_SSL_WANT_WRITE) {
/* No TLS data yet: let the upgrade loop wait for the next record. */
error_number = 0;
break;
}
if (len <= 0) {
LOG_E("WSS TLS peer closed or read failed: %d\n", len);
s->error = rws_error_new_code_descr(rws_error_code_read_write_socket, "TLS peer closed or read failed");
@@ -1848,6 +1852,7 @@ void rws_debug(void *ctx, int level, const char *file, int line, const char *str
int rws_ssl_conn(_rws_socket *s)
{
const char *pers = "talkingq-wss";
const char *stage = "allocate TLS context";
int ret = -1;
unsigned int started;
uint32_t flags;
@@ -1873,12 +1878,16 @@ int rws_ssl_conn(_rws_socket *s)
LOG_E("WSS requires valid network/RTC time before certificate verification\n");
goto exit;
}
stage = "seed RNG";
ret = mbedtls_ctr_drbg_seed(&ssl->ctr_drbg, mbedtls_entropy_func,
&ssl->entropy, (const unsigned char *)pers, strlen(pers));
if (ret != 0) goto exit;
stage = "parse root CA";
ret = mbedtls_x509_crt_parse(&ssl->cacert, (const unsigned char *)s->server_cert,
s->server_cert_len);
if (ret != 0) goto exit;
LOG_I("WSS root CA parsed successfully\n");
stage = "configure TLS";
ret = mbedtls_ssl_config_defaults(&ssl->ssl_conf, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
if (ret != 0) goto exit;
@@ -1894,6 +1903,7 @@ int rws_ssl_conn(_rws_socket *s)
/* Reuse the working PDP profile 1 TCP path. The ASR net_connect API has
a vendor-specific CID/port ABI, unlike upstream mbedTLS. */
stage = "connect TCP";
rws_socket_connect_to_host(s);
if (s->socket == RWS_INVALID_SOCKET) {
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
@@ -1903,9 +1913,11 @@ int rws_ssl_conn(_rws_socket *s)
#ifdef MBEDTLS_WITH_ASR
ssl->net_ctx.cid = 1;
#endif
stage = "set nonblocking TCP";
ret = mbedtls_net_set_nonblock(&ssl->net_ctx);
if (ret != 0) goto exit;
mbedtls_ssl_set_bio(&ssl->ssl_ctx, &ssl->net_ctx, mbedtls_net_send, mbedtls_net_recv, NULL);
stage = "TLS handshake / server certificate";
started = ql_rtos_get_systicks();
while ((ret = mbedtls_ssl_handshake(&ssl->ssl_ctx)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) goto exit;
@@ -1927,7 +1939,7 @@ int rws_ssl_conn(_rws_socket *s)
return 0;
exit:
LOG_E("WSS TLS connection failed: %d\n", ret);
LOG_E("WSS TLS connection failed at %s: %d (-0x%04x)\n", stage, ret, (unsigned int)-ret);
rws_error_delete_clean(&s->error);
s->error = rws_error_new_code_descr(rws_error_code_connect_to_host, "TLS connection or certificate verification failed");
if (s->ssl) {