Skip to content

Commit 6f127db

Browse files
committed
[nrf fromlist] samples: net: wifi: Add a script to install certs
For enterprise mode we need to install multiple certs to the TLS credentials store, so, add a helper script. Upstream PR #: 87656 Signed-off-by: Chaitanya Tata <[email protected]>
1 parent 51dcdfb commit 6f127db

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

doc/connectivity/networking/api/wifi.rst

+8
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ Run time certificates
7373
The Wi-Fi shell module uses TLS credentials subsystem to store and manage the certificates. The certificates can be added at runtime using the shell commands, see :ref:`tls_credentials_shell` for more details.
7474
The sample or application need to enable the :kconfig:option:`CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES` option to use this feature.
7575

76+
To facilitate installation of the certificates, a helper script is provided in the ``samples/net/wifi/test_certs`` directory. The script can be used to install the certificates at runtime.
77+
78+
.. code-block:: bash
79+
80+
$ samples/net/wifi/test_certs/install_certs.sh samples/net/wifi/test_certs/rsa2k
81+
82+
The script will install the certificates in the ``rsa2k`` directory to the TLS credentials store in the device over UART and using TLS credentials shell commands.
83+
7684

7785
To initiate Wi-Fi connection, the following command can be used:
7886

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) 2025, Nordic Semiconductor ASA
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# This script installs Wi-Fi certificates to a device using the `device_credentials_installer` tool.
6+
#
7+
# shellcheck disable=SC2086,SC2154
8+
# Usage:
9+
# ./install_certs.sh <path_to_certs> [port] [mode]
10+
#
11+
# Arguments:
12+
# <path_to_certs> Path to the directory containing the certificate files.
13+
# [port] (Optional) Serial port to use for communication with the device. Default is
14+
# /dev/ttyACM1.
15+
# [mode] (Optional) Mode of operation: AP or STA. Default is STA.
16+
#
17+
# Dependencies:
18+
# - `device_credentials_installer` tool must be installed. You can install it using:
19+
# pip3 install nrfcloud-utils
20+
#
21+
# Certificate Files:
22+
# The script expects the following certificate files in the specified directory:
23+
# - ca.pem: CA certificate for Wi-Fi Enterprise mode (Phase 1)
24+
# - client-key.pem: Client private key for Wi-Fi Enterprise mode (Phase 1)
25+
# - server-key.pem: Server private key for Wi-Fi Enterprise mode, for used in AP mode.
26+
# - client.pem: Client certificate for Wi-Fi Enterprise mode (Phase 1)
27+
# - server.pem: Server certificate for Wi-Fi Enterprise mode, for used in AP mode.
28+
# - ca2.pem: CA certificate for Wi-Fi Enterprise mode (Phase 2)
29+
# - client-key2.pem: Client private key for Wi-Fi Enterprise mode (Phase 2)
30+
# - client2.pem: Client certificate for Wi-Fi Enterprise mode (Phase 2)
31+
#
32+
# Each certificate file is associated with a specific security tag (sec_tag) which is used during
33+
# installation.
34+
#
35+
# The script performs the following steps:
36+
# 1. Checks if the required arguments are provided.
37+
# 2. Validates the existence of the certificate directory.
38+
# 3. Checks if the `device_credentials_installer` tool is available.
39+
# 4. Iterates over the expected certificate files and installs them to the device if they exist.
40+
# 5. Logs the success or failure of each certificate installation.
41+
#
42+
# Note:
43+
# - If a certificate file is missing, the script will skip its installation and log a warning.
44+
# - The script will terminate on the first encountered error (set -e).
45+
set -e
46+
47+
if [ -z "$1" ]; then
48+
echo -e "\033[31mError: Usage: $0 <path_to_certs> [port] [mode]\033[0m"
49+
exit 1
50+
fi
51+
52+
CERT_PATH=$1
53+
PORT=${2:-/dev/ttyACM1} # Default port is /dev/ttyACM1 if not provided
54+
MODE=${3:-STA} # Default mode is STA if not provided
55+
56+
if [ ! -d "$CERT_PATH" ]; then
57+
echo -e "\033[31mError: Directory $CERT_PATH does not exist.\033[0m"
58+
exit 1
59+
fi
60+
61+
echo -e "\033[33mWarning: Please make sure that the UART is not being used by another" \
62+
" application.\033[0m"
63+
64+
read -r -p "Press Enter to continue or Ctrl+C to exit..."
65+
66+
if ! command -v device_credentials_installer &> /dev/null; then
67+
echo -e "\033[31mError: device_credentials_installer could not be found.\033[0m"
68+
echo "Please install it using: pip3 install nrfcloud-utils"
69+
exit 1
70+
fi
71+
72+
INSTALLED_VERSION=$(pip3 show nrfcloud-utils | grep Version | awk '{print $2}')
73+
REQUIRED_VERSION="1.0.4"
74+
75+
if [ "$(printf '%s\n' "$REQUIRED_VERSION" "$INSTALLED_VERSION" | sort -V | head -n1)" != \
76+
"$REQUIRED_VERSION" ]; then
77+
echo -e "\033[31mError: device_credentials_installer >= $REQUIRED_VERSION required. Installed: \
78+
$INSTALLED_VERSION.\033[0m"
79+
echo "Update: pip3 install --upgrade nrfcloud-utils"
80+
exit 1
81+
fi
82+
83+
# From zephyr/subsys/net/lib/tls_credentials/tls_credentials_shell.c
84+
TLS_CREDENTIAL_CA_CERTIFICATE=0 # CA
85+
TLS_CREDENTIAL_PUBLIC_CERTIFICATE=1 # SERV
86+
TLS_CREDENTIAL_PRIVATE_KEY=2 # PK
87+
88+
89+
WIFI_CERT_SEC_TAG_BASE=0x1020001
90+
declare -A WIFI_CERT_SEC_TAG_MAP=(
91+
["ca.pem"]="{\"$TLS_CREDENTIAL_CA_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE))}"
92+
["client-key.pem"]="{\"$TLS_CREDENTIAL_PRIVATE_KEY\" $((WIFI_CERT_SEC_TAG_BASE + 1))}"
93+
["server-key.pem"]="{\"$TLS_CREDENTIAL_PRIVATE_KEY\" $((WIFI_CERT_SEC_TAG_BASE + 2))}"
94+
["client.pem"]="{\"$TLS_CREDENTIAL_PUBLIC_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE + 3))}"
95+
["server.pem"]="{\"$TLS_CREDENTIAL_PUBLIC_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE + 4))}"
96+
["ca2.pem"]="{\"$TLS_CREDENTIAL_CA_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE + 5))}"
97+
["client-key2.pem"]="{\"$TLS_CREDENTIAL_PRIVATE_KEY\" $((WIFI_CERT_SEC_TAG_BASE + 6))}"
98+
["client2.pem"]="{\"$TLS_CREDENTIAL_PUBLIC_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE + 7))}"
99+
)
100+
101+
# Select certificates based on mode
102+
if [ "$MODE" == "AP" ]; then
103+
CERT_FILES=("ca.pem" "server-key.pem" "server.pem")
104+
else
105+
CERT_FILES=("ca.pem" "client-key.pem" "client.pem" "ca2.pem" "client-key2.pem" "client2.pem")
106+
fi
107+
108+
total_certs=${#CERT_FILES[@]}
109+
processed_certs=0
110+
111+
for cert in "${CERT_FILES[@]}"; do
112+
processed_certs=$((processed_certs + 1))
113+
echo "Processing certificate $processed_certs of $total_certs: $cert"
114+
115+
if [ ! -f "$CERT_PATH/$cert" ]; then
116+
echo -e "\033[31mWarning: Certificate file $CERT_PATH/$cert does not exist. Skipping...\033[0m"
117+
continue
118+
fi
119+
120+
cert_info=${WIFI_CERT_SEC_TAG_MAP[$cert]}
121+
cert_type=$(echo "$cert_info" | awk -F'[{} ]' '{print $2}' | tr -d '"')
122+
cert_type_int=$((10#$cert_type))
123+
sec_tag=$(echo "$cert_info" | awk -F'[{} ]' '{print $3}' | tr -d '"')
124+
sec_tag_int=$((10#$sec_tag))
125+
if device_credentials_installer --local-cert-file "$CERT_PATH/$cert" \
126+
--cmd-type tls_cred_shell --delete \
127+
--port $PORT -S $sec_tag_int --cert-type $cert_type_int; then
128+
echo "Successfully installed $cert."
129+
else
130+
echo -e "\033[31mFailed to install $cert.\033[0m"
131+
fi
132+
done
133+
134+
135+
echo "Certificate installation process completed."

0 commit comments

Comments
 (0)