Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT with TLS1.3 on STMH563ZI nucleo board #271

Open
Sahil-Kurkure opened this issue May 1, 2024 · 2 comments
Open

MQTT with TLS1.3 on STMH563ZI nucleo board #271

Sahil-Kurkure opened this issue May 1, 2024 · 2 comments

Comments

@Sahil-Kurkure
Copy link

Hello,
I am facing an issue with MQTTs (TLS 1.3) implementation. I am using the STMH563ZI board (with TheadX as RTOS) and using the serverless emqx broker for testing.
When I try to connect to the broker over TLS 1.3, I receive an fatal alert with alertcode 10 which is "unexpected_message".
Following is my TLS setup :

/* Initialize TLS module */
_nx_secure_tls_initialize();

/* Create a TLS session */
ret = _nx_secure_tls_session_create(TLS_session_ptr, &nx_crypto_tls_ciphers_ecc,
								crypto_metadata_client, sizeof(crypto_metadata_client));
if (ret != TX_SUCCESS)
{
	Error_Handler();
}

ret = _nx_secure_tls_ecc_initialize(TLS_session_ptr,
        nx_crypto_ecc_supported_groups,
        nx_crypto_ecc_supported_groups_size,
        nx_crypto_ecc_curves);
if (ret != TX_SUCCESS)
{
	Error_Handler();
}

/* Need to allocate space for the certificate coming in from the broker. */
memset((certificate_ptr), 0, sizeof(NX_SECURE_X509_CERT));

ret = _nx_secure_tls_session_time_function_set(TLS_session_ptr, nx_secure_mqtt_tls_session_time_function);

if (ret != TX_SUCCESS)
{
	Error_Handler();
}

/* Allocate space for packet reassembly. */
ret = _nx_secure_tls_session_packet_buffer_set(TLS_session_ptr, mqtts_tls_packet_buffer,
										   sizeof(mqtts_tls_packet_buffer));
if (ret != TX_SUCCESS)
{
	Error_Handler();
}
/* allocate space for the certificate coming in from the remote host */
ret = _nx_secure_tls_remote_certificate_allocate(TLS_session_ptr, certificate_ptr,
		mqtts_tls_packet_buffer, sizeof(mqtts_tls_packet_buffer));
if (ret != TX_SUCCESS)
{
	Error_Handler();
}

/* initialize Certificate to verify incoming server certificates. */
ret = _nx_secure_x509_certificate_initialize(trusted_certificate_ptr, (UCHAR*)emqxsl_ca_der,
		emqxsl_ca_der_len, NX_NULL, 0, NULL, 0,
										 NX_SECURE_X509_KEY_TYPE_NONE);
if (ret != TX_SUCCESS)
{
	Error_Handler();
}

/* Add a CA Certificate to our trusted store */

ret = _nx_secure_tls_trusted_certificate_add(TLS_session_ptr, trusted_certificate_ptr);
if (ret != TX_SUCCESS)
{
	Error_Handler();
}

/* Add a sni extension */
nx_secure_x509_dns_name_initialize(&dns_name,(UCHAR *)mqtts_broker_name,strlen(((const char*)mqtts_broker_name)));
nx_secure_tls_session_sni_extension_set(TLS_session_ptr, &dns_name);
 _nx_secure_tls_remote_certificate_allocate(TLS_session_ptr, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
_nx_secure_tls_remote_certificate_allocate(TLS_session_ptr, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));


return ret;

I have added to root CA certificate and the SNI extension and have checked that tls1.3 is getting enabled.
Moreover, I am able to connect to the broker over tls1.2 with no issue at all (tls1.3 is disabled), but when tls1.3 is enabled the connection fails even with tls1.2

I also tried my connection with hivemq serverless cloud, it was able to communicate over tls1.2 but with tls1.3 it failed with alert code of 51 which is "decrypt_error"

Is there anything i am missing?
Thank you!

@krshnarajd
Copy link

krshnarajd commented Jul 26, 2024

NetXSecure doesn't support TLS1.3 with RSA key/certs. So if you are using RSA, you will see failure in TLS handshake.

Reference : #161

@rubenax97
Copy link

I was facing same issue while trying setting up a Modbus TLS server.... (In your case, you are the client, so you only need the root CA or Identify CA, depends on how you define trust of chain...)

Well, here you find how I faced the issue, I hope will help you to clarify and implement in your application.
FYI, I am using web addon, it is very handy for to use tcpserver implementation...

I am using XCA tool to generate CAs and crypto stuff. Below you find steps I strictly followed as.

  1. Generate root CA
    image
  2. Generate End-Identity CA (STM32 server CA) from root CA
    image
  3. In both CAs, I used EC to generate private key, because I found it is supported by netxduo secure API
    image

Then, in firmware side I make sure to define some important macros in nx_user.h file.

#define NX_SECURE_ALLOW_SELF_SIGNED_CERTIFICATES
#define NX_SECURE_TLS_ENABLE_TLS_1_3
#define NX_SECURE_AEAD_CIPHER_CHECK
#define NX_SECURE_ENABLE_AEAD_CIPHER
#define NX_SECURE_TLS_USE_SCSV_CIPHPERSUITE
#define NX_SECURE_ENABLE_ECC_CIPHERSUITE

Then in the file where you are going to initialize server/client stuff:

#define ca_cert_der             ca_cert
#define ca_cert_der_len         ca_cert_len
#define private_key_der         private_key
#define private_key_der_len     private_key_len
#define trusted_ca_cert_der     trusted_ca_cert
#define trusted_ca_cert_der_len trusted_ca_cert_len

/* TLS buffers and certificate containers. */
static CHAR  crypto_metadata_server[20000 * MAX_CLIENTS];
static UCHAR tls_packet_buffer[40000];
static NX_SECURE_X509_CERT  identify_ca;
static NX_SECURE_X509_CERT  trusted_ca;
static NX_SECURE_X509_CERT* trusted_ca_list[1];

/// ECC ciphers for TLSv1.3 is needed
extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers_ecc;
extern const USHORT               nx_crypto_ecc_supported_groups;
extern const NX_CRYPTO_METHOD*    nx_crypto_ecc_curves;
extern const UINT                 nx_crypto_ecc_supported_groups_size;

Finally, to initialize all the stuff related to TLS v1.3

/* Initialize server Identify CA */
  memset(&identify_ca, 0, sizeof(identify_ca));
  status = nx_secure_x509_certificate_initialize(&identify_ca, ca_cert_der, (USHORT)ca_cert_der_len, NX_NULL, 0,
                                                 private_key_der, (USHORT)private_key_der_len,
                                                 NX_SECURE_X509_KEY_TYPE_EC_DER);
  if (status != NX_SECURE_X509_SUCCESS)
  {
      LOG_ERROR("iface=%s, Identify CA, error: 0x%04x", iface_ptr->name, status);
      return 1;
  }

  /* Initialize Trusted CA */
  memset(&trusted_ca, 0, sizeof(trusted_ca));
  status = nx_secure_x509_certificate_initialize(&trusted_ca, trusted_ca_cert_der, (USHORT)trusted_ca_cert_der_len,
                                                 NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
  if (status != NX_SECURE_X509_SUCCESS)
  {
      LOG_ERROR("iface=%s, Trusted CA, error: 0x%04x", iface_ptr->name, status);
      return 1;
  }
  trusted_ca_list[0] = &trusted_ca;

  /* Setup TLS session data for the TCP server. */
  status = nx_tcpserver_tls_setup(&iface_ptr->server, &nx_crypto_tls_ciphers_ecc, crypto_metadata_server,
                                  sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
                                  &identify_ca, trusted_ca_list, 1, NX_NULL, 0, NX_NULL, 0);
  if (status != NX_SUCCESS)
  {
      LOG_ERROR("iface=%s, TLS configuration failed, error: 0x%04x", iface_ptr->name, status);
      return 1;
  }

  status = nx_tcpserver_tls_ecc_setup(&iface_ptr->server, &nx_crypto_ecc_supported_groups,
                                      nx_crypto_ecc_supported_groups_size, &nx_crypto_ecc_curves);
  if (status != NX_SUCCESS)
  {
      LOG_ERROR("iface=%s, TLS ecc configuration failed, error: 0x%04x", iface_ptr->name, status);
      return 1;
  }

To test all those configurations, I used openssl CLI

openssl s_client -connect 192.168.1.10:802 -tls1_3 -CAfile certs/root_CA.crt -verify_return_error -debug

I hope you find interesting and useful... 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants