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 l5/l5_e2.
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 Kconfig1.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=yKconfig1.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=81920Kconfig1.4 Include the header file for the TLS credentials library.
#include <zephyr/net/tls_credentials.h>C2. 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.pemThis 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"
};C3. 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 443C4. 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 1C4.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;
}C5. 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;
}C5.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;
}C6. 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.
| Board | Build with TF-M | Extra CMake arguments |
|---|---|---|
| nRF7002 DK | nrf7002dk_nrf5340_cpuapp_ns | N/A |
| nRF5340 DK + nRF7002 EK | nrf5340dk_nrf5340_cpuapp_ns | -DSHIELD=nrf7002ek |
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 ***
[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>TerminalTesting
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.

- Select the request method, in this case
GET. - Input the request-target, which is the hostname
echo.thingy.rocksfollowed by your specific client ID. - Remember to press button 1 on your nRF70 series board a couple of times first, to increment the counter.
- 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.
