Using SDK 3.1.2 ThreadX and NetX_Duo on a MXChip 3162 module.
My WiFi module is a client, trying to connect to secured server.
Both server A and B below have same root CA cert, Go Daddy.
Only code changes are to change the address and port number of the server for each test.
Test 1: iPad to MQTTS port 8883 on Server A (use a MQTT client app on my iPad) - Handshakes via TLS 1.0 just fine
Test 2: WiFi module to MQTTS 8883 on Server A - Fails to handshake for TLS 1.0
Test 3: WiFi module to MQTT 1883 on Server A - no encryption, clear, connects and talks just fine
Test 4: WiFi module to HTTPS 443 on Server B - Handshakes via TLS 1.2 just fine
Did this to make sure TLS is working on WiFi module, sanity check.
Could not find anything in the code to indicate the issue, unless I missed it? Can do TLS 1.2 but not TLS 1.0 If anything, I would expected the opposite to happen. Since the code debug lead to the BESL library with no source code to debug, I set up WireShark to capture the session.
Set up a Wi-Fi access point which connected to a hub which then connected to my firewall and Internet connection.
Plugged my laptop into this hub and ran WireShark to capture traffic to/from the WiFi module and my iPad for the various tests listed above.
For the failed handshake on TLS 1.0 I am seeing the client hello and server hello completing just fine. The WiFi module then sends out a client key exchange to the server and nothing more, the WiFi module promptly terminates the connection and I get error code 5015 ERROR_PRIVATE_KEY_REQUIRED. When I compare this capture to the iPad connecting to the same server via same port 8883, there are 2 additional messages from the client to the server: Change Cipher Spec, and Encrypted Handshake Message. I see all 3 messages when the WiFi module connected to 443 too.
One thing I noticed, in the WiFi module to 443 capture I see 3 separate packets in the captured data.
Client Key Exchange 193
Change Cipher Spec 60
Encrypted Handshake Message 123
= 376 bytes
For the iPad to 8883, I see all 3 in a single packet capture of size 392, which seems right.
For the WiFi module to 8883, I see 1 packet of size 321 bytes, that Wireshark only decodes as the Client Key Exchange.
So what happened to the Change Cipher and Encrypted Handshake? Why did it error out with ERROR_PRIVATE_KEY_REQUIRED ?
Attached are the WireShark captures for:
test 2 - the failed WiFi module to MQTTS port 8883 TLS 1.0 and
test 4 - the successful handshake to HTTP 443
For the 8883 capture you need to tell WireShark to decode as SSL, makes it easier to view and debug.
Before this connection attempt is made, I do a connection to NTP for current date, time on the module so the TLS should work properly. That will show up in the captures along with DHCP address assignment.
Source is very simple, follows the snip HTTPS client example, have extracted out the relevant calls and removed the error checks, etc.
host = server name
bind-address = resolved IP address of server
w_socket is global variable, not a pointer, no malloc required, same for w_context
wiced_tls_init_root_ca_certificates( GoDaddyRootCertificateAuthorityG2 );
wiced_tls_init_simple_context(&w_context, host );
wiced_tcp_connect(&w_socket, bind_address, port, SOCKET_CONNECT_TIMEOUT);
// and start tls is called with client mode and verification needed in wiced_tcp_connect()
//wiced_tcp_start_tls(socket, WICED_TLS_AS_CLIENT, TLS_VERIFICATION_REQUIRED);
I'm stuck. Is there a #define that I need to change or add? Do I need to init or clear some variable or member of a structure? Or is this a bug in BESL? Why is this failing?
Unfortunately this MQTTS connection only supports TLS 1.0 right now, no SSL 3 and no TLS 1.1 or 1.2 so have no choice.