eclipse-threadx / netxduo

Eclipse ThreadX - NetXDuo is an advanced, industrial-grade TCP/IP network stack designed specifically for deeply embedded real-time and IoT applications
https://github.com/eclipse-threadx/rtos-docs/blob/main/rtos-docs/netx-duo/index.md
MIT License
242 stars 137 forks source link

Alert value received during handshake of mTLS1.3 cannot be obtained #187

Open jkuwaha opened 1 year ago

jkuwaha commented 1 year ago

Describe the bug

When receiving an alert from the server after sending a client certificate with TLS1.3, the value of the alert cannot be obtained.

To Reproduce

Steps to reproduce the behavior:

  1. Start the server with following settings:

    • use TLS1.3
    • use mTLS
    • disconnect if the client certificate is wrong

    The command looks like openssl s_server ... -Verify 5 -verify_return_error -tls1_3

  2. Setup the client with a client certificate that is not trusted by the server.
  3. Connect to the server from the client.
  4. The server sends an alert that has level 2 and value 48 because the client certificate is not trusted.
  5. nx_nx_secure_tls_session_alert_value_get() returns an alert with level 0 and value 0.

Expected behavior nx_nx_secure_tls_session_alert_value_get() returns an alert level and value that are received.

Logs and console output

Here is a screenshot of WireShark.

image

Additional context

I placed a break point on the next line of case NX_SECURE_TLS_ALERT: in nx_secure_tls_process_record.c and reproduced the problem, but the break point isn't hit.

yanwucai commented 1 year ago

As you can see in the packet capture, the client certificate is sent after the Finished message from the server is received. The TLS 1.3 client does not wait to receive any message from the server before it finishes the handshake. The client can start sending application data immediately. This means that the client won't know whether the client certificate is accepted or not until the client reads application data from the server.

jkuwaha commented 1 year ago

Thank you for your comment, but I couldn't get your point.

This means that the client won't know whether the client certificate is accepted or not until the client reads application data from the server.

What do you mean by that? The server sent the alert with value 48. So, I thought NetX should return this alert when nx_secure_tls_session_alert_value_get() was called. Do I misunderstand something?

yanwucai commented 1 year ago

Although the server sent the alert message, the client didn't call nx_tcp_socket_receive() to receive it. After received Finished message from the server, the handshake of TLS 1.3 client can be completed directly without receiving any more messages from the server. So nx_secure_tls_session_start() is returned successfully without processing the alert message from the server. The client application usually calls nx_secure_tls_session_send() to send a request and then calls nx_secure_tls_session_receive() to receive the application data from the server. The alert message is then received and processed in this nx_secure_tls_session_receive() call.

jkuwaha commented 1 year ago

Thank you, @yanwucai.

I now understand that the alert sent by the server was in the packet pool, waiting to be received. In my case, the server sent a FIN/ACK upon receiving the client certificates, causing the disconnect callback to be called just after nx_secure_tls_session_start(). This led the client to close the connection. To check if an alert was received, I added nx_secure_tls_session_receive() before calling nx_secure_tls_session_end(). This worked very well! Thank you.

However, I was unable to catch the 'Close Notify' using the method mentioned above. Is there another way to catch it?