Skip to content

Commit 88e6de3

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 in python to make it work cross-platforms. Upstream PR #: 87656 Signed-off-by: Chaitanya Tata <[email protected]>
1 parent 415e4ae commit 88e6de3

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-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.py -p 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,130 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2025, Nordic Semiconductor ASA
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
import argparse
6+
import os
7+
import signal
8+
import subprocess
9+
import sys
10+
from importlib.metadata import PackageNotFoundError, version
11+
12+
from packaging.version import parse as parse_version
13+
14+
15+
def signal_handler(sig, frame):
16+
print('\nScript terminated by user')
17+
sys.exit(0)
18+
19+
20+
def check_requirements():
21+
try:
22+
installed_version = version('nrfcloud-utils')
23+
min_required_version = "1.0.4"
24+
if parse_version(installed_version) < parse_version(min_required_version):
25+
print(
26+
f"\033[31mError: device_credentials_installer >= {min_required_version} required. "
27+
f"Installed: {installed_version}.\033[0m"
28+
)
29+
print("Update: pip3 install --upgrade nrfcloud-utils")
30+
sys.exit(1)
31+
except PackageNotFoundError:
32+
print("\033[31mError: device_credentials_installer could not be found.\033[0m")
33+
print("Please install it using: pip3 install nrfcloud-utils")
34+
sys.exit(1)
35+
36+
37+
def main():
38+
signal.signal(signal.SIGINT, signal_handler)
39+
parser = argparse.ArgumentParser(description='Install Wi-Fi certificates', allow_abbrev=False)
40+
parser.add_argument('--path', required=True, help='Path to certificate files')
41+
parser.add_argument(
42+
'--serial-device', default='/dev/ttyACM1', help='Serial port device (default: /dev/ttyACM1)'
43+
)
44+
parser.add_argument(
45+
'--operation-mode',
46+
choices=['AP', 'STA'],
47+
default='STA',
48+
help='Operation mode: AP or STA (default: STA)',
49+
)
50+
args = parser.parse_args()
51+
52+
cert_path = args.path
53+
cert_path = args.path
54+
port = args.serial_device
55+
mode = args.operation_mode
56+
if not os.path.isdir(cert_path):
57+
print(f"\033[31mError: Directory {cert_path} does not exist.\033[0m")
58+
sys.exit(1)
59+
60+
print(
61+
"\033[33mWarning: Please make sure that the UART is not being used by another "
62+
"application.\033[0m"
63+
)
64+
input("Press Enter to continue or Ctrl+C to exit...")
65+
66+
check_requirements()
67+
68+
# TLS credential types
69+
TLS_CREDENTIAL_CA_CERTIFICATE = 0
70+
TLS_CREDENTIAL_PUBLIC_CERTIFICATE = 1
71+
TLS_CREDENTIAL_PRIVATE_KEY = 2
72+
73+
WIFI_CERT_SEC_TAG_BASE = 0x1020001
74+
WIFI_CERT_SEC_TAG_MAP = {
75+
"ca.pem": (TLS_CREDENTIAL_CA_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE),
76+
"client-key.pem": (TLS_CREDENTIAL_PRIVATE_KEY, WIFI_CERT_SEC_TAG_BASE + 1),
77+
"server-key.pem": (TLS_CREDENTIAL_PRIVATE_KEY, WIFI_CERT_SEC_TAG_BASE + 2),
78+
"client.pem": (TLS_CREDENTIAL_PUBLIC_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE + 3),
79+
"server.pem": (TLS_CREDENTIAL_PUBLIC_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE + 4),
80+
"ca2.pem": (TLS_CREDENTIAL_CA_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE + 5),
81+
"client-key2.pem": (TLS_CREDENTIAL_PRIVATE_KEY, WIFI_CERT_SEC_TAG_BASE + 6),
82+
"client2.pem": (TLS_CREDENTIAL_PUBLIC_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE + 7),
83+
}
84+
85+
cert_files = (
86+
["ca.pem", "server-key.pem", "server.pem"]
87+
if mode == "AP"
88+
else ["ca.pem", "client-key.pem", "client.pem", "ca2.pem", "client-key2.pem", "client2.pem"]
89+
)
90+
91+
total_certs = len(cert_files)
92+
for idx, cert in enumerate(cert_files, 1):
93+
print(f"Processing certificate {idx} of {total_certs}: {cert}")
94+
95+
cert_file_path = os.path.join(cert_path, cert)
96+
if not os.path.isfile(cert_file_path):
97+
print(
98+
f"\033[31mWarning: Certificate file {cert_file_path} does not exist. "
99+
f"Skipping...\033[0m"
100+
)
101+
continue
102+
103+
cert_type, sec_tag = WIFI_CERT_SEC_TAG_MAP[cert]
104+
try:
105+
subprocess.run(
106+
[
107+
"device_credentials_installer",
108+
"--local-cert-file",
109+
cert_file_path,
110+
"--cmd-type",
111+
"tls_cred_shell",
112+
"--delete",
113+
"--port",
114+
port,
115+
"-S",
116+
str(sec_tag),
117+
"--cert-type",
118+
str(cert_type),
119+
],
120+
check=True,
121+
)
122+
print(f"Successfully installed {cert}.")
123+
except subprocess.CalledProcessError:
124+
print(f"\033[31mFailed to install {cert}.\033[0m")
125+
126+
print("Certificate installation process completed.")
127+
128+
129+
if __name__ == "__main__":
130+
main()

0 commit comments

Comments
 (0)