Skip to content

wifi: enterprise: Pull support for runtime certificates #2681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 40 additions & 14 deletions doc/connectivity/networking/api/wifi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,37 +30,63 @@ Wi-Fi PSA crypto supported build

To enable PSA crypto API supported Wi-Fi build, the :kconfig:option:`CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT` and the :kconfig:option:`CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA` need to be set.

Wi-Fi Enterprise test: X.509 Certificate header generation
**********************************************************
Wi-Fi Enterprise test: X.509 Certificate management
***************************************************

Wi-Fi enterprise security requires use of X.509 certificates, test certificates
in PEM format are committed to the repo at :zephyr_file:`samples/net/wifi/test_certs` and the during the
Wi-Fi enterprise security requires use of X.509 certificates, two methods of installing certificates are supported:

Compile time certificates
-------------------------

Test certificates in PEM format are committed to the repo at :zephyr_file:`samples/net/wifi/test_certs` and the during the
build process the certificates are converted to a C header file that is included by the Wi-Fi shell
module.

If you want to use your own certificates, you can replace the existing certificates with your own certificates in the same directory.

.. code-block:: bash

$ export CERTS_DIR=samples/net/wifi/test_certs/rsa3k
$ cp client.pem $CERTS_DIR
$ cp client-key.pem $CERTS_DIR
$ cp ca.pem $CERTS_DIR
$ cp client2.pem $CERTS_DIR
$ cp client-key2.pem $CERTS_DIR
$ cp ca2.pem $CERTS_DIR
$ west build -p -b <board> samples/net/wifi -S wifi-enterprise

or alternatively copy ``rsa2k`` certificates by changing the ``CERTS_DIR`` environment variable.

.. code-block:: bash

$ cp client.pem samples/net/wifi/test_certs/
$ cp client-key.pem samples/net/wifi/test_certs/
$ cp ca.pem samples/net/wifi/test_certs/
$ cp client2.pem samples/net/wifi/test_certs/
$ cp client-key2.pem samples/net/wifi/test_certs/
$ cp ca2.pem samples/net/wifi/test_certs/
$ west build -p -b <board> samples/net/wifi -- -DEXTRA_CONF_FILE=overlay-enterprise.conf
$ export CERTS_DIR=samples/net/wifi/test_certs/rsa2k

or you can set the :envvar:`WIFI_TEST_CERTS_DIR` environment variable to point to the directory containing your certificates.

.. code-block:: bash

$ west build -p -b <board> samples/net/wifi -S wifi-enterprise -- -DWIFI_TEST_CERTS_DIR=<path_to_your_certificates>

Run time certificates
---------------------

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.
The sample or application need to enable the :kconfig:option:`CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES` option to use this feature.

For using variable size network buffer, the following overlay file can be used:
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.

.. code-block:: bash

$ west build -p -b <board> samples/net/wifi -- -DEXTRA_CONF_FILE=overlay-enterprise-variable-bufs.conf
$ samples/net/wifi/test_certs/install_certs.sh samples/net/wifi/test_certs/rsa2k

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.


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

.. code-block:: console

uart:~$ wifi connect -s <SSID> -c 149 -k 17 -w 2 -a client1 --key1-pwd whatever --key2-pwd whatever --eap-id1 id1 --eap-pwd1 pwd1
uart:~$ wifi connect -s <SSID> -c 149 -k 7 -w 2 -a client1 --key1-pwd whatever --key2-pwd whatever

Server certificate is also provided in the same directory for testing purposes.
Any AAA server can be used for testing purposes, for example, ``FreeRADIUS`` or ``hostapd``.
Expand Down
2 changes: 0 additions & 2 deletions drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,6 @@ static inline enum wifi_security_type drv_to_wifi_mgmt(int drv_security_type)
return WIFI_SECURITY_TYPE_WAPI;
case NRF_WIFI_EAP:
return WIFI_SECURITY_TYPE_EAP;
case NRF_WIFI_EAP_TLS_SHA256:
return WIFI_SECURITY_TYPE_EAP_TLS_SHA256;
default:
return WIFI_SECURITY_TYPE_UNKNOWN;
}
Expand Down
2 changes: 0 additions & 2 deletions include/zephyr/net/wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ enum wifi_security_type {
WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2,
/** EAP PEAP security - Enterprise. */
WIFI_SECURITY_TYPE_EAP_PEAP_TLS,
/** EAP TLS SHA256 security - Enterprise. */
WIFI_SECURITY_TYPE_EAP_TLS_SHA256,
/** FT-PSK security */
WIFI_SECURITY_TYPE_FT_PSK,
/** FT-SAE security */
Expand Down
8 changes: 1 addition & 7 deletions modules/hostap/src/supp_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,6 @@ static struct wifi_eap_config eap_config[] = {
"auth=MSCHAPV2"},
{WIFI_SECURITY_TYPE_EAP_PEAP_TLS, WIFI_EAP_TYPE_PEAP, WIFI_EAP_TYPE_TLS, "PEAP",
"auth=TLS"},
{WIFI_SECURITY_TYPE_EAP_TLS_SHA256, WIFI_EAP_TYPE_TLS, WIFI_EAP_TYPE_NONE, "TLS", NULL},
};

int process_cipher_config(struct wifi_connect_req_params *params,
Expand Down Expand Up @@ -517,10 +516,6 @@ int process_cipher_config(struct wifi_connect_req_params *params,
}
}

if (params->security == WIFI_SECURITY_TYPE_EAP_TLS_SHA256) {
cipher_config->key_mgmt = "WPA-EAP-SHA256";
}

for (index = 0; index < ARRAY_SIZE(ciphers); index++) {
if (cipher_capa == ciphers[index].capa) {
cipher_config->group_cipher = ciphers[index].name;
Expand Down Expand Up @@ -557,8 +552,7 @@ static int is_eap_valid_security(int security)
security == WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2 ||
security == WIFI_SECURITY_TYPE_EAP_PEAP_GTC ||
security == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 ||
security == WIFI_SECURITY_TYPE_EAP_PEAP_TLS ||
security == WIFI_SECURITY_TYPE_EAP_TLS_SHA256);
security == WIFI_SECURITY_TYPE_EAP_PEAP_TLS);
}
#endif

Expand Down
10 changes: 0 additions & 10 deletions samples/net/wifi/shell/overlay-enterprise.conf

This file was deleted.

4 changes: 0 additions & 4 deletions samples/net/wifi/shell/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ CONFIG_NET_STATISTICS_PERIODIC_OUTPUT=n
CONFIG_WIFI=y
CONFIG_WIFI_LOG_LEVEL_ERR=y
CONFIG_NET_L2_WIFI_SHELL=y

CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=70000

# printing of scan results puts pressure on queues in new locking
# design in net_mgmt. So, use a higher timeout for a crowded
# environment.
Expand Down
135 changes: 135 additions & 0 deletions samples/net/wifi/test_certs/install_certs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/usr/bin/env bash
# Copyright (c) 2025, Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
#
# This script installs Wi-Fi certificates to a device using the `device_credentials_installer` tool.
#
# shellcheck disable=SC2086,SC2154
# Usage:
# ./install_certs.sh <path_to_certs> [port] [mode]
#
# Arguments:
# <path_to_certs> Path to the directory containing the certificate files.
# [port] (Optional) Serial port to use for communication with the device. Default is
# /dev/ttyACM1.
# [mode] (Optional) Mode of operation: AP or STA. Default is STA.
#
# Dependencies:
# - `device_credentials_installer` tool must be installed. You can install it using:
# pip3 install nrfcloud-utils
#
# Certificate Files:
# The script expects the following certificate files in the specified directory:
# - ca.pem: CA certificate for Wi-Fi Enterprise mode (Phase 1)
# - client-key.pem: Client private key for Wi-Fi Enterprise mode (Phase 1)
# - server-key.pem: Server private key for Wi-Fi Enterprise mode, for used in AP mode.
# - client.pem: Client certificate for Wi-Fi Enterprise mode (Phase 1)
# - server.pem: Server certificate for Wi-Fi Enterprise mode, for used in AP mode.
# - ca2.pem: CA certificate for Wi-Fi Enterprise mode (Phase 2)
# - client-key2.pem: Client private key for Wi-Fi Enterprise mode (Phase 2)
# - client2.pem: Client certificate for Wi-Fi Enterprise mode (Phase 2)
#
# Each certificate file is associated with a specific security tag (sec_tag) which is used during
# installation.
#
# The script performs the following steps:
# 1. Checks if the required arguments are provided.
# 2. Validates the existence of the certificate directory.
# 3. Checks if the `device_credentials_installer` tool is available.
# 4. Iterates over the expected certificate files and installs them to the device if they exist.
# 5. Logs the success or failure of each certificate installation.
#
# Note:
# - If a certificate file is missing, the script will skip its installation and log a warning.
# - The script will terminate on the first encountered error (set -e).
set -e

if [ -z "$1" ]; then
echo -e "\033[31mError: Usage: $0 <path_to_certs> [port] [mode]\033[0m"
exit 1
fi

CERT_PATH=$1
PORT=${2:-/dev/ttyACM1} # Default port is /dev/ttyACM1 if not provided
MODE=${3:-STA} # Default mode is STA if not provided

if [ ! -d "$CERT_PATH" ]; then
echo -e "\033[31mError: Directory $CERT_PATH does not exist.\033[0m"
exit 1
fi

echo -e "\033[33mWarning: Please make sure that the UART is not being used by another" \
" application.\033[0m"

read -r -p "Press Enter to continue or Ctrl+C to exit..."

if ! command -v device_credentials_installer &> /dev/null; then
echo -e "\033[31mError: device_credentials_installer could not be found.\033[0m"
echo "Please install it using: pip3 install nrfcloud-utils"
exit 1
fi

INSTALLED_VERSION=$(pip3 show nrfcloud-utils | grep Version | awk '{print $2}')
REQUIRED_VERSION="1.0.4"

if [ "$(printf '%s\n' "$REQUIRED_VERSION" "$INSTALLED_VERSION" | sort -V | head -n1)" != \
"$REQUIRED_VERSION" ]; then
echo -e "\033[31mError: device_credentials_installer >= $REQUIRED_VERSION required. Installed: \
$INSTALLED_VERSION.\033[0m"
echo "Update: pip3 install --upgrade nrfcloud-utils"
exit 1
fi

# From zephyr/subsys/net/lib/tls_credentials/tls_credentials_shell.c
TLS_CREDENTIAL_CA_CERTIFICATE=0 # CA
TLS_CREDENTIAL_PUBLIC_CERTIFICATE=1 # SERV
TLS_CREDENTIAL_PRIVATE_KEY=2 # PK


WIFI_CERT_SEC_TAG_BASE=0x1020001
declare -A WIFI_CERT_SEC_TAG_MAP=(
["ca.pem"]="{\"$TLS_CREDENTIAL_CA_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE))}"
["client-key.pem"]="{\"$TLS_CREDENTIAL_PRIVATE_KEY\" $((WIFI_CERT_SEC_TAG_BASE + 1))}"
["server-key.pem"]="{\"$TLS_CREDENTIAL_PRIVATE_KEY\" $((WIFI_CERT_SEC_TAG_BASE + 2))}"
["client.pem"]="{\"$TLS_CREDENTIAL_PUBLIC_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE + 3))}"
["server.pem"]="{\"$TLS_CREDENTIAL_PUBLIC_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE + 4))}"
["ca2.pem"]="{\"$TLS_CREDENTIAL_CA_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE + 5))}"
["client-key2.pem"]="{\"$TLS_CREDENTIAL_PRIVATE_KEY\" $((WIFI_CERT_SEC_TAG_BASE + 6))}"
["client2.pem"]="{\"$TLS_CREDENTIAL_PUBLIC_CERTIFICATE\" $((WIFI_CERT_SEC_TAG_BASE + 7))}"
)

# Select certificates based on mode
if [ "$MODE" == "AP" ]; then
CERT_FILES=("ca.pem" "server-key.pem" "server.pem")
else
CERT_FILES=("ca.pem" "client-key.pem" "client.pem" "ca2.pem" "client-key2.pem" "client2.pem")
fi

total_certs=${#CERT_FILES[@]}
processed_certs=0

for cert in "${CERT_FILES[@]}"; do
processed_certs=$((processed_certs + 1))
echo "Processing certificate $processed_certs of $total_certs: $cert"

if [ ! -f "$CERT_PATH/$cert" ]; then
echo -e "\033[31mWarning: Certificate file $CERT_PATH/$cert does not exist. Skipping...\033[0m"
continue
fi

cert_info=${WIFI_CERT_SEC_TAG_MAP[$cert]}
cert_type=$(echo "$cert_info" | awk -F'[{} ]' '{print $2}' | tr -d '"')
cert_type_int=$((10#$cert_type))
sec_tag=$(echo "$cert_info" | awk -F'[{} ]' '{print $3}' | tr -d '"')
sec_tag_int=$((10#$sec_tag))
if device_credentials_installer --local-cert-file "$CERT_PATH/$cert" \
--cmd-type tls_cred_shell --delete \
--port $PORT -S $sec_tag_int --cert-type $cert_type_int; then
echo "Successfully installed $cert."
else
echo -e "\033[31mFailed to install $cert.\033[0m"
fi
done


echo "Certificate installation process completed."
29 changes: 29 additions & 0 deletions samples/net/wifi/test_certs/rsa2k/ca.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIE+TCCA+GgAwIBAgIUH614zvmCngpSc26BLLFu2loqvfgwDQYJKoZIhvcNAQEL
BQAwgZIxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNv
bWV3aGVyZTEUMBIGA1UECgwLRXhhbXBsZSBJbmMxIDAeBgkqhkiG9w0BCQEWEWFk
bWluQGV4YW1wbGUub3JnMSYwJAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1
dGhvcml0eTAgFw0yNTAzMjcxMjUwNDhaGA8yMDUyMDgxMTEyNTA0OFowgZIxCzAJ
BgNVBAYTAkZSMQ8wDQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEU
MBIGA1UECgwLRXhhbXBsZSBJbmMxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1w
bGUub3JnMSYwJAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALljCArLJs7rdS4pJDrpbSd3
pNCo1skN3h9FSdboWnz5uvy4dUfOQcPzd1i/Kav7R+eURTIlIe24slDobYW7dS+u
U+mlw8yzd6Xs9L8BvHrE/JvHMdaCubSWJwJ+BtTZMAvwfpysw0TrYgUw10v4O6PU
0ri80I/79IKXCQjLnoqrf7OylYnSeuufMrcojZlqMD444EcJS8OAhm648D7w9xWp
YwGhhV7gLgFZfIZ3vq/VQE6//pasHZ4P2bdej4Up7Nhsqa3qLtPYlUsJB8uTp04h
YLA600hKoGKJiW1fHrmVIQiYamwkpUSmhY1mw/RJ0GbWE1BT+vLC2BMckw+cwF0C
AwEAAaOCAUEwggE9MB0GA1UdDgQWBBTgzBbVi3ycphRotu7Am6ynMwVAyTCB0gYD
VR0jBIHKMIHHgBTgzBbVi3ycphRotu7Am6ynMwVAyaGBmKSBlTCBkjELMAkGA1UE
BhMCRlIxDzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRQwEgYD
VQQKDAtFeGFtcGxlIEluYzEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5v
cmcxJjAkBgNVBAMMHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ghQfrXjO
+YKeClJzboEssW7aWiq9+DAPBgNVHRMBAf8EBTADAQH/MDYGA1UdHwQvMC0wK6Ap
oCeGJWh0dHA6Ly93d3cuZXhhbXBsZS5jb20vZXhhbXBsZV9jYS5jcmwwDQYJKoZI
hvcNAQELBQADggEBAAV8StX4zFbOqcNVzF0JaZGu7CquFR4pOjCbM9XJVcwCxc0+
DtIxy+w9KMLGgwB6LHh51tAExCR3UTktG8FqFxdjESCD8qlQoLU1uzt0kadKvQUr
wjn8ToEp1UP8UZa+SzaXVAYv09DC+VMYqBmkUtze/F5LC0LMWQBR3bn2EGdwBoMl
k2Gq6BdJZRCotyraSvG01mMyORY6UzLi25WFVg6B284VlD0cqFqmUMEmk2f76Ix3
WpUkoGZ/ArAoS6+vaFmSrhZ9W+YBfBoBgjXrGMKi2dkUUngbm4yGxrhnN1MFu2lA
xnBWRxSQjzLGzqQP/bfxAVlNyXwQNPETGVZpGzc=
-----END CERTIFICATE-----
29 changes: 29 additions & 0 deletions samples/net/wifi/test_certs/rsa2k/ca2.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIE+TCCA+GgAwIBAgIUH614zvmCngpSc26BLLFu2loqvfgwDQYJKoZIhvcNAQEL
BQAwgZIxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNv
bWV3aGVyZTEUMBIGA1UECgwLRXhhbXBsZSBJbmMxIDAeBgkqhkiG9w0BCQEWEWFk
bWluQGV4YW1wbGUub3JnMSYwJAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1
dGhvcml0eTAgFw0yNTAzMjcxMjUwNDhaGA8yMDUyMDgxMTEyNTA0OFowgZIxCzAJ
BgNVBAYTAkZSMQ8wDQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEU
MBIGA1UECgwLRXhhbXBsZSBJbmMxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1w
bGUub3JnMSYwJAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALljCArLJs7rdS4pJDrpbSd3
pNCo1skN3h9FSdboWnz5uvy4dUfOQcPzd1i/Kav7R+eURTIlIe24slDobYW7dS+u
U+mlw8yzd6Xs9L8BvHrE/JvHMdaCubSWJwJ+BtTZMAvwfpysw0TrYgUw10v4O6PU
0ri80I/79IKXCQjLnoqrf7OylYnSeuufMrcojZlqMD444EcJS8OAhm648D7w9xWp
YwGhhV7gLgFZfIZ3vq/VQE6//pasHZ4P2bdej4Up7Nhsqa3qLtPYlUsJB8uTp04h
YLA600hKoGKJiW1fHrmVIQiYamwkpUSmhY1mw/RJ0GbWE1BT+vLC2BMckw+cwF0C
AwEAAaOCAUEwggE9MB0GA1UdDgQWBBTgzBbVi3ycphRotu7Am6ynMwVAyTCB0gYD
VR0jBIHKMIHHgBTgzBbVi3ycphRotu7Am6ynMwVAyaGBmKSBlTCBkjELMAkGA1UE
BhMCRlIxDzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRQwEgYD
VQQKDAtFeGFtcGxlIEluYzEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5v
cmcxJjAkBgNVBAMMHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ghQfrXjO
+YKeClJzboEssW7aWiq9+DAPBgNVHRMBAf8EBTADAQH/MDYGA1UdHwQvMC0wK6Ap
oCeGJWh0dHA6Ly93d3cuZXhhbXBsZS5jb20vZXhhbXBsZV9jYS5jcmwwDQYJKoZI
hvcNAQELBQADggEBAAV8StX4zFbOqcNVzF0JaZGu7CquFR4pOjCbM9XJVcwCxc0+
DtIxy+w9KMLGgwB6LHh51tAExCR3UTktG8FqFxdjESCD8qlQoLU1uzt0kadKvQUr
wjn8ToEp1UP8UZa+SzaXVAYv09DC+VMYqBmkUtze/F5LC0LMWQBR3bn2EGdwBoMl
k2Gq6BdJZRCotyraSvG01mMyORY6UzLi25WFVg6B284VlD0cqFqmUMEmk2f76Ix3
WpUkoGZ/ArAoS6+vaFmSrhZ9W+YBfBoBgjXrGMKi2dkUUngbm4yGxrhnN1MFu2lA
xnBWRxSQjzLGzqQP/bfxAVlNyXwQNPETGVZpGzc=
-----END CERTIFICATE-----
30 changes: 30 additions & 0 deletions samples/net/wifi/test_certs/rsa2k/client-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIcm3x/CvLYRcCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECCSqbBrS+vObBIIEyPSMbzL5DvaJ
tW/lEoNvmujkYw/qADyExm4JidoemiTxMJB6TkXJE+W8glDeY+TCZUD6UyeiSx7J
HC1R2rQmpy91LT5o6P7Eyq/VHIsXVE77rS91NCKjiljdPWbzkLFo5oNwguhsvKI9
YjU8m0V6KVLx21DZFDi5OZQ8g0ULu9FR9WIr4eDUnAIjJnpqw00hZF6FVKe7lu9t
2uCiKABXpODMqQyrDrTTsQNB4MV8axVWMaYW4P6JVf40ByzA4ISNYhmFH3DWMlAH
c6LhZstT7n3lXbpsq3pTvn/07+5yuTIvOmFvOoUnXo+kIU7gf1ODma7kPHrcD62c
9ZgMh/Y90YcQamoLUXJqKBk96ybj9v4p6CTzJC8vOj8GOJqEoUgs6lNYrNQmdJka
InZJnMfCgX67g60NrQ7vb/LPXTs1gShk/fn2EdLCvhqJNQwNgLjwFtio2DObBD4b
kuIV/h83moZ/yGrW2PPjxDrzWCxgFhMXs8kGZX6119J8Ki8L+EgKXz0Vfed6XQP6
RK2anaQzmtJgM4gzzXDOPBPKYDMjqZHqZpMCl1J6TOYbVELDu+OAPGrLSXt71O+T
toPVrUNdKvYB5H4hosoqMiyeNGwEVjFlSKEInSM6IlwWK2+/xeqTued74nKgj/Je
xmLbZEurHtOctY0807gj2aNO2/iR4n+1kk9nniBcZNJ7la5GEqAp4wRSH2KI+hu0
YoJHLtRX/BccawOTvWnLXOsbBTxXtZV9m4ojLbqCzpEV5alFkO0ycP/ao6A/ZTej
52X01EoUi7Nq5uoIxx+BKj5LN4Pa0Wpe4/DryiEqjSQ2sZMnkD+DhHw/soGcJrJm
s9zV0YFfFk9Flfnq/9uteHOj+CLxE4BQCpaEBkE+2IooU2Vtw9i5YOeQB+4971XE
JFBqNknjSfFqaL9zzBliKA9bizZawBub/HUX5P+3k71761k+Li1ID+RYOhTGjqKh
ws8bke2BtAOB/vccxQGYEOdi8U6+AgK7Dz1AmMQhLlDA8S7qAwodLmnaC6WhP1rA
1koQYnAGCxOcARTZCLzlfidNf1KzYMRdSVjTh9QAGW7cxEnNEnai5nU4VXUVT3xB
LWRP98yWzOIsQLFtXzjE0P+ESYGOsQj8aVyy/QHSOg5oEHxZ/myUbr1QB58Z+VKa
T8/EE2lQazINMIxfsxjDygHX3iF3BlxpwCBk2ykdbfqQFwZ3cr1l53ixuKqd2pTV
xsEhuAvAfJ1OadUM8HefT+ijUuKPUowtcrcA8URqgy1V/vgcM0qiw7fWysKK7oWl
L7Oa3JfTE1mpZuocOvF7e5ueNzIgEgnxQEkEE3AJmS0YxMqI6ShTnUx6p79OlVZr
/Izdkwqqhene+zudNd3z0TMhkjI8LZa6x4SBfCZmCOzOgoZ9XMrf80S/9CKTLWFv
UrLOe8RJz/6SYweQTMakejC/sbHSSTrqmIf9mrVLP1sMBm8R7TPLMRt8CFNtuYB0
3nHO9kP7qT3U3sTZ9A0NQyaOfQYcWSLSGBkLSJAM3wh590hp7i6hnM3FeOYY3+lL
2a9q59B2H3HJfSUUCXtPA8wsEkZyCfz+y5YGscrhQcCbBq1FkkarluKJFonFCEKK
D4mU9Io0mhON+5ZNhwqurQ==
-----END ENCRYPTED PRIVATE KEY-----
Loading
Loading