Feedback
Feedback

If you are having issues with the exercises, please create a ticket on DevZone: devzone.nordicsemi.com
Click or drag files to this area to upload. You can upload up to 2 files.

Exercise 2

Adding TLS to the HTTP connection

In this exercise, we will alter the code from the previous exercise to add security to our HTTP connection. We will learn how to achieve this by using certificates, to verify the authenticity of the server, and also by establishing TLS-secured communication between the device and the server.

Exercise steps

In the GitHub repository for this course, go to the base code for this exercise, found in lesson5/wififund_less5_exer2.

1. Include and configure the TLS credentials module.

1.1 Enable and configure the TLS credentials module.

This is similar to what we did in the previous lesson, with the addition being CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION, which we add in step 1.2. This Kconfig symbol is needed for adding support for the Server Name Indication extension. SNI is an extension to the TLS protocol which facilitates server verification using certificates.

Add the following lines to the prj.conf file

CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_TLS_CREDENTIALS=y
CONFIG_MBEDTLS_RSA_C=y
CONFIG_MBEDTLS_DHM_C=y 
Kconfig

1.2 Enable support for server name indication (SNI).

Enable support for SNI in the mbedTLS cryptography library through the Kconfig CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION.

CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y
Kconfig

1.3 Increase the size allocated to the mbedTLS heap, if building with TF-M.

Open boards/nrf7002dk_nrf5340_cpuapp_ns.conf or boards/nrf5340dk_nrf5340_cpuapp_ns.conf, depending on the board you are using, and increase the mbedTLS heap size by changing the following Kconfig line

CONFIG_MBEDTLS_HEAP_SIZE=81920
Kconfig

1.4 Include the header file for the TLS credentials library.

#include <zephyr/net/tls_credentials.h>
C

2. Add the necessary certificate to the application.

2.1 To verify the authenticity of the HTTP server, we will use the Amazon Root CA 1 certificate, which you will find in the base code for this exercise, saved as ca_certificate.pem.

2.2 Convert the certificate into a header file in C.

We will use a Python script (can be found in the scripts subdirectory in this exercise’s code base directory) that converts a certificate into a header file certificate.h that will contain the converted certificate as a C string.

Open a new terminal, navigate to the script folder (lesson5/wififund_less5_exer2/script), and then run the Python script cert_to_header.py with the name of the certificate you want to convert as an argument.

python.exe .\cert_to_header.py ca_certificate.pem

This will generate the converted certificate.h in the /src subdirectory

2.3 Include the certificate file in the application.

static const char ca_certificate[] = {
#include "certificate.h"
};
C

3. Change the HTTP port number.

Change the HTTP port we are using, by changing the value to 443, which is the standard TLS port for HTTP.

#define HTTP_PORT 443
C

4. Store the credential in the device.

4.1 Define a macro for the security tag used to store the certificate.

#define HTTP_TLS_SEC_TAG 1
C

4.2 Define a function to add the credentials.

In the function setup_credentials(), add the TLS credential by calling tls_credential_add().

Add the following code snippet in main.c

int err = tls_credential_add(HTTP_TLS_SEC_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, ca_certificate, sizeof(ca_certificate));
if (err < 0) {
	LOG_ERR("Failed to add TLS credentials, err: %d", err);
	return err;
}
C

5. Set the TLS relevant socket options for the socket

Before connecting to the HTTP server, we need to set the TLS relevant socket options using setsockopt(), which has the following signature

We need to set the security tag of the stored certificate and the hostname of the HTTP server.

5.1 Configure the socket with the security tag for the certificate.

Set the option TLS_SEC_TAG_LIST to the security tag for the certificate, stored in HTTP_TLS_SEC_TAG.

This is the security tag that the credentials will be referenced with, and must be attached to the socket before connecting.

sec_tag_t sec_tag_opt[] = {
	HTTP_TLS_SEC_TAG,
};
err = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_opt, sizeof(sec_tag_opt));
if (err) {
	LOG_ERR("Failed to set TLS security TAG list, err: %d", errno);
	(void)close(sock);
	return -errno;
}
C

5.2 Configure the socket with the hostname of the HTTP server.

Set the option TLS_HOSTNAME to be the hostname for the HTTP server.

err = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, HTTP_HOSTNAME, sizeof(HTTP_HOSTNAME));
if (err) {
	LOG_ERR("Failed to set TLS_HOSTNAME option, err: %d", errno);
	(void)close(sock);
	return -errno;
}
C

6. Build and flash the application to your board.

This exercise uses the PSA backend for storing the Wi-Fi credentials. Therefore, you must build with TF-M.

BoardBuild with TF-M
nRF7002 DKnrf7002dk_nrf5340_cpuapp_ns
nRF5340 DK + nRF7002 EKnrf5340dk_nrf5340_cpuapp_ns

If necessary, input the commands to connect to Wi-Fi, as we have done in previous exercises.

On a successful connection, you should see the following log output.

*** Booting nRF Connect SDK 2.6.1-3758bcbfa5cd ***
[00:00:01.476,898] <inf> Lesson5_Exercise2: Waiting to connect to Wi-Fi
[00:00:07.511,627] <inf> Lesson5_Exercise2: Network connected
[00:00:07.558,746] <inf> Lesson5_Exercise2: IPv4 address of HTTP server found 54.230.111.103
[00:00:08.277,709] <inf> Lesson5_Exercise2: Successfully connected to server
[00:00:08.849,731] <inf> Lesson5_Exercise2: Response status: Created
[00:00:08.849,792] <inf> Lesson5_Exercise2: Successfully acquired client ID: <your client ID>
Terminal

Testing

7. Set up an HTTP client.

To test the application, we need to setup an HTTP client to remotely read the counter value that was sent to the HTTP server. You will need an HTTP client running on your PC, smartphone, or tablet. In this exercise, we will use HTTPie’s web app, an in-browser HTTP client that does not require any installation or setup.

8. Copy the client ID from your device’s log output.

Copy the unique client ID that your device retrieves when first connecting to the HTTP server, it is marked in the log above as <your_client_ID>. You will need your device’s specific client ID to be able to retrieve the value that your device has posted to the server.

9. Open a web browser and go to httpie.io/app.

  1. Select the request method, in this case GET.
  2. Input the request-target, which is the hostname echo.thingy.rocks followed by your specific client ID.
  3. Remember to press button 1 on your nRF70 series board a couple of times first, to increment the counter.
  4. Click send to send the HTTP request to the server.

10. Observe the response from the server, number “4” for example, at the bottom of this window.

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

  • 8 or more characters
  • Upper and lower case letters
  • At least one number or special character

Forgot your password?
Enter the email associated with your account, and we will send you a link to reset your password.