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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user