I am running into an issue with getting HTTPS to work on NONOS v3.0. I've tried the stock libssl and libmbedtls but both of them get stuck after calling espconn_secure_connect(), which in turn fires the following message:
client handshake start.
I tried building my own version of mbedtls using the source provided by Espressif and still ran into the same failure as above. Tried running at 160 MHz and still the same failure.
It looks like my code is getting stuck in the mbedtls library here:
if (TLSmsg->ssl.state == MBEDTLS_SSL_HELLO_REQUEST){
if (Threadmsg->preverse != NULL){
struct espconn *accept_conn = NULL;
struct espconn *espconn = Threadmsg->preverse;
struct sockaddr_in name;
socklen_t name_len = sizeof(name);
remot_info *pinfo = NULL;
espconn_get_connection_info(espconn, &pinfo , ESPCONN_SSL);
if (espconn->link_cnt == 0x01)
return ERR_ISCONN;
ret = mbedtls_net_accept(&TLSmsg->listen_fd, &TLSmsg->fd, NULL, 0, NULL);
lwIP_REQUIRE_NOERROR(ret, exit);
accept_conn = mbedtls_espconn_new();
lwIP_REQUIRE_ACTION(accept_conn, exit, ret = ERR_MEM);
Threadmsg->pespconn = accept_conn;
/*get the remote information*/
getpeername(TLSmsg->fd.fd, (struct sockaddr*)&name, &name_len);
Threadmsg->pcommon.remote_port = htons(name.sin_port);
os_memcpy(Threadmsg->pcommon.remote_ip, &name.sin_addr.s_addr, 4);
espconn->proto.tcp->remote_port = htons(name.sin_port);
os_memcpy(espconn->proto.tcp->remote_ip, &name.sin_addr.s_addr, 4);
espconn_copy_partial(accept_conn, espconn);
/*insert the node to the active connection list*/
espconn_list_creat(&plink_active, Threadmsg);
os_printf("server handshake start.\n");
} else{
os_printf("client handshake start.\n");
}
config_flag = mbedtls_msg_config(TLSmsg);
if (config_flag){
// mbedtls_keep_alive(TLSmsg->fd.fd, 1, SSL_KEEP_IDLE, SSL_KEEP_INTVL, SSL_KEEP_CNT);
system_overclock();
} else{
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
lwIP_REQUIRE_NOERROR(ret, exit);
}
}
system_soft_wdt_stop();
while ((ret = mbedtls_ssl_handshake(&TLSmsg->ssl)) != 0) {
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
ret = ESPCONN_OK;
break;
} else{
break;
}
}
system_soft_wdt_restart();
While the mbedtls_ssl_handshake loop has disabled the software watchdog, it seems like the handshake process is so slow that it triggers the hardware watchdog. So, after a several seconds, the HW WDT triggers and the ESP reboots.
The same API endpoint works great on the Arduino stack. Both BearSSL and axTLS work fine. However, when digging into the Arduino stack, it looks like they have some magic. The yield() function allows background processes to run and prevents the HW WDT from triggering.
size_t WiFiClientSecure::write(Stream& stream)
{
size_t totalSent = 0;
size_t countRead;
size_t countSent;
if (!_ssl)
{
return 0;
}
do {
uint8_t temp[256]; // Temporary chunk size same as ClientContext
countSent = 0;
countRead = stream.readBytes(temp, sizeof(temp));
if (countRead) {
countSent = write(temp, countRead);
totalSent += countSent;
}
yield(); // Feed the WDT
} while ( (countSent == countRead) && (countSent > 0) );
return totalSent;
}
So, it seems like I have the following options. Anyone else have better ideas?
- - Port the magic yield() function into NONOS.. Not sure if it is possible?
- Find the easiest cipher suite that my server supports and pray that the ESP is quick enough to handle it
FYI, here is the list of cipher suites that my server supports. I would guess that AES128-SHA is the most lightweight cipher suite? Anyone knows what that corresponds to in the mbedtls library?
- - ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES128-SHA256
- ECDHE-RSA-AES128-SHA256
- ECDHE-ECDSA-AES128-SHA
- ECDHE-RSA-AES128-SHA
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384
- ECDHE-ECDSA-AES256-SHA384
- ECDHE-RSA-AES256-SHA384
- ECDHE-RSA-AES256-SHA
- ECDHE-ECDSA-AES256-SHA
- AES128-GCM-SHA256
- AES128-SHA256
- AES128-SHA
- AES256-GCM-SHA384
- AES256-SHA256
- AES256-SHA