MicroEJ + SSL (hostname verification)

Hello,

We are currently using the initial MicroEJ port for ESP32.

After upgrading to ESP-IDF 5.5.4, we noticed that the SSL implementation used by MicroEJ (ESP-IDF + C port) has never been validating the server certificate’s common name / hostname.

(woops…)

Some context:

  • With older versions of ESP-IDF / mbedTLS, it was possible to complete the SSL handshake without explicitly setting or verifying the hostname. This results in an insecure connection, since only the certificate authority and basic checks are performed.
  • In newer versions, this is no longer acceptable. As described here: CVE-2025-27809 FAQ — Mbed TLS documentation , hostname verification is now a required part of a secure TLS setup, otherwise the connection cannot be considered safe.

What we need to do:

  • As stated in the mbedTLS documentation, mbedtls_ssl_set_hostname() must be called before mbedtls_ssl_handshake().

The issue we are facing:

  • In the MicroEJ C API, we are unable to find any way to pass or configure the hostname for the SSL context.

Note:

  • The call to mbedtls_ssl_handshake() is performed inside LLNET_SSL_SOCKET_IMPL_initialHandShake() located in components/microej/ssl/src/LLNET_SSL_SOCKET_impl.c.

Has anyone already dealt with this in a MicroEJ + ESP-IDF integration, or found a proper way to inject the hostname into the SSL layer?

:growing_heart:

Hi,

In the ESP32-S3-DevKitC-1-N8R8 VEE Port 2.6.2, this is actually already handled
correctly. The hostname is passed into the SSL layer, so the server certificate’s hostname does get verified.

You can see it here:

LLNET_SSL_SOCKET_impl.c, inside LLNET_SSL_SOCKET_IMPL_create():

if ((NULL != hostname) && (hostnameLen > 0)) {
// Check if the given host is an IP address or is actually a host name.
struct sockaddr_in hostAddr;
int is_valid_addr = inet_pton(AF_INET, (const char*) hostname, &(hostAddr.sin_addr));
if (0 == is_valid_addr) {
mbedtls_ssl_set_hostname(&(ssl_ctx->ssl_context), (char*)hostname);
}
}

A few things worth noting:

  • The hostname is forwarded from the Managed Code layer all the way down to this native function (it’s a parameter of LLNET_SSL_SOCKET_IMPL_create), so you don’t need to inject it manually.
  • mbedtls_ssl_set_hostname() is called here, during socket creation, which is before the handshake — the handshake itself happens later in LLNET_SSL_SOCKET_IMPL_initialHandShake(). So the ordering required by mbedTLS is respected.

The cleanest way to get the fix is to update your NET Pack to 10.7.0 (at minimum) and migrate the net/ssl/security implementation of your legacy VEE Port to the ones provided in the net/, ssl/ and security/ folders of the ESP32-S3 VEE Port BSP:

Hope this helps!

Alex