1#!/usr/bin/env python3
2# Copyright (c) 2025, Nordic Semiconductor ASA
3# SPDX-License-Identifier: Apache-2.0
4
5import argparse
6import logging
7import os
8import signal
9import subprocess
10import sys
11
12
13def signal_handler(sig, frame):
14    logger.info('Script terminated by user')
15    sys.exit(0)
16
17
18def main():
19    signal.signal(signal.SIGINT, signal_handler)
20    parser = argparse.ArgumentParser(description='Install Wi-Fi certificates', allow_abbrev=False)
21    parser.add_argument('--path', required=True, help='Path to certificate files')
22    parser.add_argument(
23        '--serial-device', default='/dev/ttyACM1', help='Serial port device (default: /dev/ttyACM1)'
24    )
25    parser.add_argument(
26        '--operation-mode',
27        choices=['AP', 'STA'],
28        default='STA',
29        help='Operation mode: AP or STA (default: STA)',
30    )
31    parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output')
32    args = parser.parse_args()
33
34    # Configure logging
35    log_level = logging.DEBUG if args.verbose else logging.INFO
36    logging.basicConfig(level=log_level, format='%(asctime)s - %(levelname)s - %(message)s')
37    global logger
38    logger = logging.getLogger(__name__)
39
40    cert_path = args.path
41    port = args.serial_device
42    mode = args.operation_mode
43    if not os.path.isdir(cert_path):
44        logger.error(f"Directory {cert_path} does not exist.")
45        sys.exit(1)
46
47    logger.warning(
48        "Please make sure that the Serial port is not being used by another application."
49    )
50    input("Press Enter to continue or Ctrl+C to exit...")
51
52    # TLS credential types
53    TLS_CREDENTIAL_CA_CERTIFICATE = 0
54    TLS_CREDENTIAL_PUBLIC_CERTIFICATE = 1
55    TLS_CREDENTIAL_PRIVATE_KEY = 2
56
57    WIFI_CERT_SEC_TAG_BASE = 0x1020001
58    WIFI_CERT_SEC_TAG_MAP = {
59        "ca.pem": (TLS_CREDENTIAL_CA_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE),
60        "client-key.pem": (TLS_CREDENTIAL_PRIVATE_KEY, WIFI_CERT_SEC_TAG_BASE + 1),
61        "server-key.pem": (TLS_CREDENTIAL_PRIVATE_KEY, WIFI_CERT_SEC_TAG_BASE + 2),
62        "client.pem": (TLS_CREDENTIAL_PUBLIC_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE + 3),
63        "server.pem": (TLS_CREDENTIAL_PUBLIC_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE + 4),
64        "ca2.pem": (TLS_CREDENTIAL_CA_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE + 5),
65        "client-key2.pem": (TLS_CREDENTIAL_PRIVATE_KEY, WIFI_CERT_SEC_TAG_BASE + 6),
66        "client2.pem": (TLS_CREDENTIAL_PUBLIC_CERTIFICATE, WIFI_CERT_SEC_TAG_BASE + 7),
67    }
68
69    cert_files = (
70        ["ca.pem", "server-key.pem", "server.pem"]
71        if mode == "AP"
72        else ["ca.pem", "client-key.pem", "client.pem", "ca2.pem", "client-key2.pem", "client2.pem"]
73    )
74
75    total_certs = len(cert_files)
76    for idx, cert in enumerate(cert_files, 1):
77        logger.info(f"Processing certificate {idx} of {total_certs}: {cert}")
78
79        cert_file_path = os.path.join(cert_path, cert)
80        if not os.path.isfile(cert_file_path):
81            logger.warning(f"Certificate file {cert_file_path} does not exist. Skipping...")
82            continue
83
84        cert_type, sec_tag = WIFI_CERT_SEC_TAG_MAP[cert]
85        try:
86            command = [
87                "./scripts/utils/tls_creds_installer.py",
88                "-p",
89                port,
90                "-l",
91                cert_file_path,
92                "-d",
93                "-t",
94                str(cert_type),
95                "-S",
96                str(sec_tag),
97            ]
98            if args.verbose:
99                command.append("-v")
100
101            subprocess.run(command, check=True)
102            logger.info(f"Successfully installed {cert}.")
103        except subprocess.CalledProcessError:
104            logger.error(f"Failed to install {cert}.")
105
106    logger.info("Certificate installation process completed.")
107
108
109if __name__ == "__main__":
110    main()
111