cancel
Showing results for 
Search instead for 
Did you mean: 

AzureRTOS/ThreadX MQTTs (mutual TLS)

Davide Dalfra
Associate III

Hello Community,

 

I'm setting up a test with NetxDuo + MQTT over TLS (aka MQTTs, port 8883) on a STM32F429NIx.
As far as i see from the example available it consider a scenario where the client verify the certs provided by the server with the supplied CA.

This could work, but it's not mutual-tls, while I'm trying to have a mTLS (mutual-tls ) where also the client_cert and client_key are used.

I see the tls_callback function specified in the nxd_mqtt_client_secure_connect have two NX_SECURE_X509_CERT * parameter.

 

UINT tls_setup_callback(NXD_MQTT_CLIENT *client_pt, NX_SECURE_TLS_SESSION *TLS_session_ptr, NX_SECURE_X509_CERT *certificate_ptr,   NX_SECURE_X509_CERT *trusted_certificate_ptr)

 

 

Always from the examples i see trusted_certificate_ptr is used for the CA, while the certificate_ptr for the cert received from the server.

Then my question is: where i have to load the client certs? Have i misunderstood the certificate_ptr parameter so i have to setup the client_cert/key here?

Does NetxDuo/MQTT support mTLS (mutualTLS) mqtt connection?

 

If someone could point me out where to watch at this, it would be really appreciated.

 

Regards

Davide

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

Yes it is what I am saying.

The certificate_ptr is used to receive the server's certificate.

View solution in original post

8 REPLIES 8
Guillaume K
ST Employee

Hello

In tls_setup_callback(), after creating a session, try to use nx_secure_tls_local_certificate_add() with an initialized certificate for your client (initialized with nx_secure_x509_certificate_initialize()).

I think it is the server that decides to ask the client to provide a certificate . 

For example, if you use mosquitto MQTT server, you must configure it for TLS with its own certificate and CA, and enable the option to require client certificates: "require_certificate true".

Of course, the client certificate must match with the CA configured in the server.

Hello Guillaume,

 

Thanks for your reply.
In the meantime i got some progress and i done something like this in the tls_callback.

 

NX_SECURE_X509_CERT client_cert = { 0 };
UINT tls_setup_callback(NXD_MQTT_CLIENT *client_pt, NX_SECURE_TLS_SESSION *TLS_session_ptr, NX_SECURE_X509_CERT *certificate_ptr,   NX_SECURE_X509_CERT *trusted_certificate_ptr)
{
  UINT ret = NX_SUCCESS;
  NX_PARAMETER_NOT_USED(client_pt);

  /* Initialize TLS module */
  nx_secure_tls_initialize();

  /* Create a TLS session */
  ret = nx_secure_tls_session_create(TLS_session_ptr, &nx_crypto_tls_ciphers,
                                     crypto_metadata_client, sizeof(crypto_metadata_client));
  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));

  /* Allocate space for packet reassembly. */
  ret = nx_secure_tls_session_packet_buffer_set(TLS_session_ptr, tls_packet_buffer,
                                                sizeof(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,
                                                  tls_packet_buffer, sizeof(tls_packet_buffer));
  if (ret != TX_SUCCESS)
  {
    Error_Handler();
  }
  
  
  /*************************************** CA SECTIOn *****************************************/
  ret = nx_secure_x509_certificate_initialize(trusted_certificate_ptr, (UCHAR*)ca_der,
                                              ca_der_len, NX_NULL, 0, NULL, 0,
                                              NX_SECURE_X509_KEY_TYPE_NONE);
  
  
  if (ret != TX_SUCCESS)
  {
    MQTT_LOG("Certificate issue..\nPlease make sure that your X509_certificate is valid. \n");
    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)
  {
    MQTT_LOG("Failed to load CA-certificate\n");
    Error_Handler();
  }
  

  /*******************************************************************************************/
  
  
  /************************************ CLIENT CERT SECTION ************************************/
  ret = nx_secure_x509_certificate_initialize(&client_cert, (UCHAR*)default_client_der,
                                              default_client_der_len, NX_NULL, 0, default_client_key_der, default_client_key_der_len,
                                              NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
  if (ret != TX_SUCCESS)
  {
    MQTT_LOG("Failed to load client cert / key\n");
    Error_Handler();
  }
  
  
  ret = nx_secure_tls_local_certificate_add(TLS_session_ptr, &client_cert);
  if (ret != TX_SUCCESS)
  {
    Error_Handler();
  }
  
  /************************************************************************************************/
  


  
  


  return ret;
}

 

Basically i used an external object (declared before the function) and then loaded to the TLS_session_ptr.
Is this what you was saying , or is it more correct to initialize on the certificate_ptr?

 

 

Regards

Davide

Yes it is what I am saying.

The certificate_ptr is used to receive the server's certificate.

Great!


Thanks

 

Davide

Hi Davide,

I am having the same question as you in your original post. Can you please elaborate a little bit more of how did you load the CA, client_key and client_cert files into the project so that you can have the pointers to those?

Best wishes,

Anh

Hi,

You simply import them into the project as simple files.
Remember to transform the certificate (usually .der format) to byte-array style. If you have the certificate in PEM , convert it to der by using openssl.

Once you get the .der format, you need to transform into a byte-array style: ST suggest xxd for doing that, but there's plenty of solutions(i.e. HxD).

 

Regards

Davide

Hi Davide,

Thank you for the reply. I would like to ask about the client key file. According to the netx-duo-secure-tls guide, the client key must also be in DER format. It suggests to convert using the command 

openssl rsa -inform PEM -in <private key> -outform DER -out private.key

 After having the CA certificate and client certificate in DER format, I got client key in DER format as well. But the connection could not be established. I tested with MQTTX and mosquitto, and the connection can only be made if I used client key in PEM format. 

So my question is, have you successfully connected by using client key in DER format as described in the NetX Duo Secure TLS guide?

Thanks,

Anh.

Davide Dalfra
Associate III

Hi Anh,

 

Yes, the certificate i have loaded are in DER format(in form of a C-Array). Please remember that the key encoding have to be made on PKCS1.
What kind of error are you encountering? Each NetX* function return with a code which is a start point on where to dig-into.

On the other hand, pc-client (i use Mqtt.fx) can support both PEM and DER format for estabilishing the connection to the broker. I suggest you first try to use generated DER(s) on a pc to test everything hase been set up correctly and then move back to the MCU.

 

 

Regards

Davide